OOF/HAS Create/Update API

Interface DefintionDescription

URI

https://{host}:{port}/api/oof/v1/placement

Operation Type

POST

Content-Type

application/json

Request Header

Header NameRequired?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

AttributeRequired?CardinalityContentValuesDescription

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

AttributeRequired?CardinalityContentValuesDescription

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.

callbackHeaderN1JSON 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

AttributeRequired?CardinalityContentValuesDescription

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.

subscriberInfoN1SubscriberInfo Object
The information of a service subscriber.

PlacementDemand Object

AttributeRequired?CardinalityContentValuesDescription

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

AttributeRequired?CardinalityContentValuesDescription

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'.

subscriberCommonSiteIdN1String
Id representing a subscriber location.

ModelMetaData Object

AttributeRequired?CardinalityContentValuesDescription

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

AttributeRequired?CardinalityContentValuesDescription

identifierType

Y

1

String

serviceInstanceId, vnfName, cloudRegionId, vimId

The type of a candidate.

identifiers

Y

1..N

List of Strings


A list of identifiers.

cloudOwnerC1String
The name of a cloud owner. Only required if identifierType is cloud_region_id.

ServiceInfo Object

AttributeRequired?CardinalityContentValuesDescription

serviceInstanceId

Y

1

String


A service instance id associated with a request.

modelInfo

Y

1

ModelMetaData Object


A list of identifiers.

serviceNameY1String
The name of a service.

LicenseInfo Object

AttributeRequired?CardinalityContentValuesDescription

licenseDemands

Y

1..N

List of LicenseDemands Object


A list of resources for license selection.

LicenseDemands Object

AttributeRequired?CardinalityContentValuesDescription

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

AttributeRequired?CardinalityContentValuesDescription

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

AttributeRequired?CardinalityContentValuesDescription

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 NameRequired?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.

AttributeNAttribute 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

AttributeRequired?CardinalityContentValuesDescription

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

AttributeRequired?CardinalityContentValuesDescription

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

AttributeRequired?CardinalityContentValuesDescription
-

Y

1..N

List of PlacementSolution Object


A list of placement solutions.

PlacementSolution Object

AttributeRequired?CardinalityContentValuesDescription

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

AttributeRequired?CardinalityContentValuesDescription

key

Y

1

String


An attribute name.

value

Y

1

String


An attribute value.

LicenseSolutions Object

AttributeRequired?CardinalityContentValuesDescription

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 CodeResponse PhraseDescription

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.

520Solver errorRequested number of solutions cannot be found.

Request Example


SO-OOF/HAS Request Example
{
  "requestInfo": {
    "transactionId": "xxx-xxx-xxxx",
    "requestId": "yyy-yyy-yyyy",
    "callbackUrl": "https://wiki.onap.org:5000/callbackUrl/",
    "sourceId": "SO",
    "requestType": "create",
    "numSolutions": 1,
    "optimizers": ["placement"],
    "timeout": 600
  },
  "placementInfo": {
  	"requestParameters": { "customerLatitude": 32.89748, "customerLongitude": -97.040443, "customerName": "xyz" },
    "subscriberInfo": {"globalSubscriberId": "xxx-xx-xxx", "subscriberName": "subscriber_x"},
  	"placementDemands": [
    	{
      		"resourceModuleName": "vGMuxInfra",
      		"serviceResourceId": "vGMuxInfra-xx",
      		"tenantId": "vGMuxInfra-tenant",
      		"resourceModelInfo": {
        		"modelInvariantId": "vGMuxInfra-modelInvariantId",
        		"modelVersionId": "vGMuxInfra-versionId",
        		"modelName": "vGMuxInfra-model",
        		"modelType": "resource",
        		"modelVersion": "1.0",
        		"modelCustomizationName": "vGMuxInfra-customeModelName"
      		}
    	},
    	{
      		"resourceModuleName": "vG",
      		"serviceResourceId": "71d563e8-e714-4393-8f99-cc480144a05e",
      		"tenantId": "vG-tenant",
      		"resourceModelInfo": {
        		"modelInvariantId": "vG-modelInvariantId",
        		"modelVersionId": "vG-versionId",
        		"modelName": "vG-model",
        		"modelType": "resource",
        		"modelVersion": "1.0",
        		"modelCustomizationName": "vG-customeModelName"
      		},
			"existingCandidates": [ 
				{
					"identifierType": "serviceInstanceId", 
					"cloudOwner": "", 
					"identifiers": ["gjhd-098-fhd-987"]
				}
    		],
			"excludedCandidates": [ 
				{
					"identifierType": "serviceInstanceId", 
					"cloudOwner": "", 
					"identifiers": ["gjhd-098-fhd-987"]
				},
				{
					"identifierType": "vimId", 
					"cloudOwner": "vmware", 
					"identifiers": ["NYMDT67"]
				}
    		],
			"requiredCandidates": [ 
				{
					"identifierType": "vimId", 
					"cloudOwner": "amazon", 
					"identifiers": ["TXAUS219"]
				}
    		]
		}
  	]
  },
  "serviceInfo": {
    "serviceInstanceId": "d61b2543-5914-4b8f-8e81-81e38575b8ec",
	"serviceName": "vCPE",
    "modelInfo": {
      "modelInvariantId": "vCPE-invariantId",
      "modelVersionId": "vCPE-versionId",
      "modelName": "vCPE-model",
      "modelType": "service",
      "modelVersion": "1.0",
      "modelCustomizationName": "vCPE-customeModelName"
    }
  },
  "licenseInfo": {
      "licenseDemands": [
        {
          "resourceModuleName": "vGMuxInfra",
          "serviceResourceId": "vGMuxInfra-xx",
          "resourceModelInfo": {
            "modelInvariantId": "vGMuxInfra-modelInvariantId",
            "modelVersionId": "vGMuxInfra-versionId",
            "modelName": "vGMuxInfra-model",
            "modelType": "resource",
            "modelVersion": "1.0",
            "modelCustomizationName": "vGMuxInfra-customeModelName"
          },
          "existingLicenses": {
            "entitlementPoolUUID": ["87257b49-9602-4ca1-9817-094e52bc873b", "43257b49-9602-4fe5-9337-094e52bc9435"],
            "licenseKeyGroupUUID": ["87257b49-9602-4ca1-9817-094e52bc873b", "43257b49-9602-4fe5-9337-094e52bc9435"]
          }
        }
      ]
  }
}

Synchronous Response Example


SO-OOF/HAS Response Example
{
  "transactionId": "xxx-xxx-xxxx",
  "requestId": "yyy-yyy-yyyy",
  "requestStatus": "accepted",
  "statusMessage": ""
}

Asynchronous Response Example


SO-OOF/HAS Response Example
{
  "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"]
		},
        "assignmentInfo": [
          { "key": "cloudOwner", "value": "amazon" },
          { "key": "vnfHostName", "value": "ahr344gh" },
          { "key": "isRehome", "value": "False" },
          { "key": "cloudRegionId", "value": "1ac71fb8-ad43-4e16-9459-c3f372b8236d" }
        ]
      },
      {
        "resourceModuleName": "vG",
        "serviceResourceId": "someResourceId",
        "solution": {
        	"identifierType": "cloudRegionId", 
			"cloudOwner": "amazon", 
			"identifiers": ["gjhd-098-fhd-987"]
		},
        "assignmentInfo": [
          { "key": "cloudOwner", "value": "amazon" },
          { "key": "cloudRegionId", "value": "1ac71fb8-ad43-4e16-9459-c3f372b8236d" }
        ]
      }
     ]
    ],
    "licenseSolutions": [
      {
        "resourceModuleName": "vGMuxInfra",
        "serviceResourceId": "someResourceId",
        "entitlementPoolUUID": ["1ac71fb8-ad43-4e16-9459-c3f372b8236d", "834fc71fb8-ad43-4fh7-9459-c3f372b8236f"],
        "licenseKeyGroupUUID": ["1ac71fb8-ad43-4e16-9459-c3f372b8236d", "834fc71fb8-ad43-4fh7-9459-c3f372b8236f"],
        "entitlementPoolInvariantUUID": ["1ac71fb8-ad43-4e16-9459-c3f372b8236d", "834fc71fb8-ad43-4fh7-9459-c3f372b8236f"],
        "licenseKeyGroupInvariantUUID": ["1ac71fb8-ad43-4e16-9459-c3f372b8236d", "834fc71fb8-ad43-4fh7-9459-c3f372b8236f"]
      }
    ]
  }
}

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.

Optimization Query Policy Example
{
  "service": "optimizationQueryPolicy",
  "policyName": "oofBeijing.queryPolicy_vCPE",
  "description": "Optimization query policy for vCPE",
  "templateVersion": "0.0.1",
  "version": "oofBeijing",
  "priority": "3",
  "riskType": "test",
  "riskLevel": "2",
  "guard": "False",
  "content": {
    "queryProperties": [
      {"attribute":"locationId", "value": "orderInfo.customerLocation"},
      {"attribute":"id", "value": "orderInfo.vpnInfo"},
      {"attribute":"upstreamBW", "value": "orderInfo,vpnInfo"}
    ],
    "policyScope": ["vCPE", "US", "INTERNATIONAL", "ip", "vGMuxInfra", "vG"],
    "type": "optimizationQueryPolicy"
  }
}
requestParameter JSON blob Example
{
  	"orderInfo": {
		"customerLocation": {
			"latitude": "30.98",
			"longitude": "34.23",
			"locationId": "NJBD34"
  		},
		"vpnInfo": {
			[
				"id": 200,
				"upsteamBW": "10Gbps",
				"downstreamBW": "100Gbps"
			],
			[
				"id": 200,
				"upsteamBW": "10Gbps",
				"downstreamBW": "100Gbps"
			]
		}
  	}
}


OOF/HAS API document (pdf format)


  • No labels

46 Comments

  1. Few comments queries on the APIs 

    • I believe this is the API of HAS which is primarily used by OSDF after translating the policy and request to a form which can be passed on to HAS - Is this right ? Does HAS implement a dedicated Request Handler ? It will be helpful to indicate which component in OSDF exposes this API (HAS or Request Hanbler) . In the diagram here, I can see two layers of API - Homing API and HAS API. I believe the above description is for HAS API. 
    • In the RequestInfo object, I am not sure if requestType (create,update, delete) attribute is required. It may be more suitable to use REST HTTP methods POST,PUT/PATCH,DELETE instead. 
    • In the SynchronousResponse , I dont see the solutions object. Is it intentional ? Or is it expected that in Synchronos response , solutions will be sent to the callback URL at a later point in time (which I believe qualifies for asynchronous) ? 
    • In the RequestInfo object, can you please clarify where numSolutions attribute is enforced ? Is it in HAS Controller or in the HAS Solver ? What kind of error message (if at all sent) is returned if the solutions has less number of solutions than numSolutions 
    • In the PlacementDemand Object resourceModuleName and resourceModelInfo are being referred to the SDC models. I believe this is corresponding to the ID stored in the SDC catalog. In the diagram here I dont see any interface with SDC Catalog. Other option might be to query this in SO Runtime catalog. Or is this queried in A&AI against the Service/Resource Instance ? Please share how the resource details are queried and validated. 
    • In the Candidates object, I guess each cloud-region might have multiple tenants. Do we also need to include a candidate to represent tenants. 
    • w.e.t ServiceInfo Object and ModelMetadata Object - Both corresponds to Service Instance (which I believe in A&AI). Can you please clarify if OOF is invoked before or after making an entry in A&AI. I guess these two objects expects an entry in A&AI irrespective of the state of the ServiceInstance. 
    • w.r.t LicenseInfo, LicenseDemands and LicenseModel object - Is it always mandatory (as noted in the Request Body) to have the LicenseInfo present in the request ? Cant request have only a placement info and request info. I guess the license need to be managed by the policy manager or a dedicated license manager. Not sure if OOF/HAS requeires this as a mandatory parameter. 
    • Again for license, in LicenseModel EntitelmentPool UUID and LicenseKeyGroupUUID are given. I guess OOF checks for resources having the corresponding EntitilementPool and LicenseKeyGroup. Here I think these two (EntitlementPool and LicenKeyGroup) are associated with a FeatureGroup in SDC. Is more suitable to have the feature group ID here than the EP and LKG UUIDs. Additionally how OOF HAS check the thresholds/limits corresponding to each feature group without having a placeholder in the request to compare against. 
      • This is the northbound API used by a client to send a homing request to OOF. Once OSDF receives the request, OSDF constructs an API call for HAS using the information received from both request and policies.
      • The RequestInfo object is modeled such that it can be applicable to various optimization applications. For HAS, the requestType can be replaced by REST actions; however, it may not hold true for other types of optimization application. So, to keep the options open for other values of a requestType, it is better to capture in an attribute rather than REST actions.
      • The synchronous response just informs a client about acceptance/rejection of a request and the rational behind it, and so, the solution object is not captured.
      • Good catch. The numSolution attribute represents the number of expected solutions and is interpreted by an optimizer (e.g. HAS Solver). If the expected number of solutions cannot be found, the application is expected to return an asynchronous response with a failed status to client. We should capture such error using a distinct response code, which is missing in the HTTP Response Code table.
      • Upon receiving a request for a service instantiation from VID, SO fetches the service model from the SDC repo, decomposes the model, and extracts out resourceModuleName and resourceModelInfo information. This information is eventually passed to OOF/HAS over the northbound API.
      • Good suggestion; however, it depends on the scope of HAS. Currently, HAS conducts homing at the cloud region level and to the best of my understanding tenant-level information may not be required. Shankaranarayanan Puzhavakath Narayanan and Matti Hiltunen can give more details on this point.
      •  serviceModelInfo (Captures the meta information of a service model) is extracted out from a service model by SO and serviceInstanceId (Unique id associated with a service instantiation request to SO) is issued by SO prior to making a homing call to OOF/HAS.
      • LicenseInfo, LicenseDemands and LicenseModel objects should be optional for vCPE use case. In fact, it's a good idea to capture the mandatory/optional aspects of an attribute in policies, such that we can customize API validation depending on the type of a service. Here, mandatory is a typo which needs to be fixed.
      • The requestParameters field captures service ordering information that captures qualifiers based on which EntitilementPool and LicenseKeyGroup are selected. I agree, both of these fields can be collectively represented by a featureGroup; however, these fields (EntitilementPool and LicenseKeyGroup) within a featureGroup have different capabilities. For example, entitlementPool within a feature group may support different bandwidths. OOF is expected to filter out the entitlementPools that meets customer bandwidth demand. Thus, the response API must captures EntitilementPool and LicenseKeyGroup rather than featureGroup.

      1. 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. 

    1. 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

      1. 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"

        1. I updated (1) the request example by capturing placementInfo element and (2) the definition of RequestInfo object.

  2. Comments more:

    1.  licenseDemands cardinality should be 1...N

    2.  licenseSolutions cardinality should be 1...N

    3.  should Candidates object add the tenant, zone and make it more flexible and make it as an combined conditions?

    4.  could assignmentInfo be specified in the PlacementSolution object?  does it consider to support vimid, regionid, tenant, zone or zone group?
    5. Placementsolution includes the identifierType and identifier, which are as a structure of Candidates object. could it is possible use the Candidates object diectly in the Placementsolution object?
    6. is ""ComprehensiveSolution Object"" needed? SO-OOF/HAS Response Example does not show it. 

      Notes1: why put the license and placement together in one API?
      Notes2: what's difference between the candidates object and assignmentInfo ?
    1. 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.

  3. 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.

    1. 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?



      1. 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. 

      2. 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

      3. 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.

    2. 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

      1. 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

        1. 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} 

          1. 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?

            1. Would the following structure be good enough to capture the details?

              "requiredCandidates": [ 
                   {
              	"identifier_type": "vim_id", 
              	"cloud_owner": "amazon", 
              	"identifiers": ["TXAUS219","NJMDT219"]
                   },
                   {
              	"identifier_type": "vim_id", 
              	"cloud_owner": "vmware", 
              	"identifiers": ["NYNY219","FLORD219"]
                   }
                ]


              1. @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

                1. Just updated the example. Is that what you are looking for?

              2. 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..

                1. I am with you, but we don't have a better alternative.

  4. 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) 

    • Retrieve maximum download/upload speed for an access service at a specified address
    •  Check if we can deliver new access and IPTV (4k) services at a specified address 
    • Check if we can deliver new IP TV service at the same location of an existing and active Accesse service (i.e. without explicitly specifying address) 
    • Check if we can upgrade the download speed of an existing and active service from 100 Mb/s to 600Mb/s

    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 

    • Alignment with a standard spec  and no need to invent new terms and APIs , at the same time TMF spec are generic in nature to repereset any ServiceQualificationItems such as place and service characteristics (such as HPA params, bandwidth etc) 
    • ServiceQualification is a referenceable record which can be modified on demand and can be monitored with Listeners in an asynchronous manner. 
    • Flexibility to represent any type of future constraints without changing the OOF implementation (through service qualification item). 
    • Can be extended this via External API in future. Else there will be mapping required from External API which may not align well. 
    • Availability of rich input which helps in implementing more accurate optimization algorithms - like related party, service specification or catalog item details, service parameters (service characteristics) etc. 
    1. 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. 

    2. 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

  5. Cory and I approve this API on behalf of SO.

  6. 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.

    1. Thanks Avteet! I just updated the specs and examples with camel case only.

  7. Hi Ankit,

    There appears to be a typo. Shouldn't vmId be vimId?

    1. You caught me! I just fixed the typo.

  8. 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 the requestParameter JSON blob Example for customer details.

    1. 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.

  9. The requestStatus and StatusMessage in the table is inconsistent with the examples provided. Can you please clarify.


    1. What is in the table:

      statusMessage

      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!",

        1. Please clarify what the possible values/enums are for requestStatus?
        2.  I dont think we should put special characters in the statusMessage...
        3. "Reasoning if requestStatus is failure." - this makes me think statusMessage will only be populated if requestStatus is failure but in the example it is populated for a success/completed.
        4. Suggestion:
          1. maybe make "requestStatus" the actual status so either "completed" or "pending"
          2. make "statusMessage" tell whether it was successful or not so it would either be "success" or "failure".
        1. Thanks Cory! I just fixed the inconsistencies that you pointed out.

  10. 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

        

    1. 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.

  11. Hi Ankitkumar,

    I believe, SO will receive placement suggestions in either of the following ways -

    1. By a notification from HAS - if it is, then how HAS will be fed with that notification end point?
    2. Or, SO will keep on polling for a duration - if it is, then what will be the end point for that?

    Thanks

    1. OOF will asynchronously send the recommendations on a callback url/end point that is sent in a request.

      Ankit

    2. 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.

  12. Hi AnkitkumarShankaranarayanan

    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


    1. 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.

      1. right, there can be multiple solutions...