Updated the sync and async responses and addes testcases related to policy adaptors.
Issue-ID: OPTFRA-208
Change-Id: Ia0f88df1b897b6158674f3c3a7ef239f2328dcfc
Signed-off-by: Ankitkumar Patel <ankit@research.att.com>
local_policies:
global_disabled: True
local_placement_policies_enabled: True
+ placement_policy_dir_vcpe: "../test/policy-local-files/"
placement_policy_files_vcpe: # workaroud for policy platform glitches (or "work-arounds" for other components)
- Affinity_vCPE_1.json
- Capacity_vGMuxInfra.json
- Capacity_vG_1.json
- Distance_vGMuxInfra_1.json
- Distance_vG_1.json
- - Min_Guarantee_vGMuxInfra_1.json
- Placement_Optimization_1.json
- QueryPolicy_vCPE.json
+ - QueryPolicy_vCPE_2.json
- hpa_policy_vGMuxInfra_1.json
- hpa_policy_vG_1.json
- vnfPolicy_vG.json
ACCEPTED_MESSAGE_TEMPLATE = Template("""
{
"requestId": "{{ request_id }}",
- "text": "{{ description }}"
+ "transactionId": "{{ transaction_id }}",
+ "requestStatus": "{{ request_status }}",
+ "statusMessage": "{{ status_message }}"
}
""")
if service_type == "scheduling":
return lp.get('{}_policy_dir'.format(service_type)), lp.get('{}_policy_files'.format(service_type))
else:
- required_node = osdf_config.core['policy_info'][service_type]['policy_scope']['service_name']
- model_name = retrieve_node(req_json, required_node)
- service_name = model_name # TODO: data_mapping.get_service_type(model_name)
+ service_name = req_json['serviceInfo']['serviceName'] # TODO: data_mapping.get_service_type(model_name)
return lp.get('{}_policy_dir_{}'.format(service_type, service_name.lower())), \
lp.get('{}_policy_files_{}'.format(service_type, service_name.lower()))
return None
:param service_type: the type of service to call: "placement", "scheduling"
:return: policies associated with this request and provStatus retrieved from Subscriber policy
"""
- prov_status = []
req_info = request_json['requestInfo']
req_id = req_info['requestId']
metrics_log.info(MH.requesting("policy", req_id))
else:
policies = remote_api(request_json, osdf_config, service_type)
- return policies, prov_status
+ return policies
For placement and other requests, there are encoded JSONs inside the request or policy,
so we need to expand it and then do a search over the parent plus expanded JSON.
"""
- req_json_copy = copy.deepcopy(req_json) # since we expand the JSON in place, we work on a copy
- if 'orderInfo' in req_json_copy['placementInfo']:
- req_json_copy['placementInfo']['orderInfo'] = json.loads(req_json_copy['placementInfo']['orderInfo'])
+ req_json_copy = copy.deepcopy(req_json)
info = dot_notation(req_json_copy, reference)
- return list_flatten(info) if isinstance(info, list) else info
\ No newline at end of file
+ return list_flatten(info) if isinstance(info, list) else info
from osdf import ACCEPTED_MESSAGE_TEMPLATE
-def osdf_response_for_request_accept(req_id="", text="", response_code=202, as_http=True):
+def osdf_response_for_request_accept(request_id="", transaction_id="", request_status="", status_message="",
+ response_code=202, as_http=True):
"""Helper method to create a response object for request acceptance, so that the object can be sent to a client
- :param req_id: request ID provided by the caller
- :param text: extra text description about accepting the request (e.g. "Request accepted")
+ :param request_id: request ID provided by the caller
+ :param transaction_id: transaction ID provided by the caller
+ :param request_status: the status of a request
+ :param status_message: details on the status of a request
:param response_code: the HTTP status code to send -- default is 202 (accepted)
:param as_http: whether to send response as HTTP response object or as a string
:return: if as_http is True, return a HTTP Response object. Otherwise, return json-encoded-message
"""
- response_message = ACCEPTED_MESSAGE_TEMPLATE.render(description=text, request_id=req_id)
+ response_message = ACCEPTED_MESSAGE_TEMPLATE.render(request_id=request_id, transaction_id=transaction_id,
+ request_status=request_status, status_message=status_message)
if not as_http:
return response_message
"""
status_message = conductor_response["plans"][0].get("message")
templ = Template(open(template_placement_response).read())
- return json.loads(templ.render(composite_solutions=[], requestId=request_id,
+ return json.loads(templ.render(composite_solutions=[], requestId=request_id, license_solutions=[],
transactionId=raw_response.headers.get('transaction_id', ""),
- statusMessage=status_message, json=json))
+ requestState="completed", statusMessage=status_message, json=json))
{
"requestId": "{{requestId}}",
"transactionId": "{{transacationId}}",
- "startTime": "{{startTime}}",
- "responseTime": "{{responseTime}}",
- "requestType": "{{requestType}}",
"requestState": "{{requestState}}",
- "statusMessage": "{{statusMessage}}",
- "percentProgress": "{{percentProgress}}",
- "solutionInfo": {
- "placement": {{ json.dumps(composite_solutions) }},
- "licenseInfo":{ "featureGroupId": "{{featureGroupId}}" }
+ "statusMessage": "{{statusMessage}}"
+ "solutions": {
+ "placementSolutions": {{ json.dumps(composite_solutions) }},
+ "licenseSolutions":{{ json.dumps(license_solutions) }}
}
}
t = Thread(target=process_placement_opt, args=(request_json, policies, osdf_config))
t.start()
audit_log.info(MH.accepted_valid_request(req_id, request))
- return osdf.operation.responses.osdf_response_for_request_accept(
- req_id=req_id, text="Accepted placement request. Response will be posted to callback URL")
+ return osdf.operation.responses.osdf_response_for_request_accept(request_id=req_id,
+ transaction_id=request_json['transactionId'],
+ request_status="accepted",
+ status_message="")
@app.errorhandler(500)
local_policies:
global_disabled: False
local_placement_policies_enabled: True
+ placement_policy_dir_vcpe: "../test/policy-local-files/"
placement_policy_files_vcpe: # workaroud for policy platform glitches (or "work-arounds" for other components)
- Affinity_vCPE_1.json
- Capacity_vGMuxInfra.json
- Capacity_vG_1.json
- Distance_vGMuxInfra_1.json
- Distance_vG_1.json
- - Min_Guarantee_vGMuxInfra_1.json
- Placement_Optimization_1.json
- QueryPolicy_vCPE.json
+ - QueryPolicy_vCPE_2.json
- hpa_policy_vGMuxInfra_1.json
- hpa_policy_vG_1.json
- vnfPolicy_vG.json
--- /dev/null
+{
+ "service": "optimizationQueryPolicy",
+ "policyName": "oofBeijing.queryPolicy_vCPE",
+ "description": "Optimization query policy for vCPE",
+ "templateVersion": "0.0.1",
+ "version": "oofBeijing",
+ "priority": "5",
+ "riskType": "test",
+ "riskLevel": "2",
+ "guard": "False",
+ "content": {
+ "queryProperties": [
+ {"attribute":"locationId", "attribute_location": "customerLocation", "value": ""},
+ {"attribute":"id", "attribute_location": "vpnInfo.vpnId", "value": ""},
+ {"attribute":"upstreamBW", "attribute_location": "vpnInfo.upstreamBW", "value": ""},
+ {"attribute":"customerLatitude", "attribute_location": "customerLatitude", "value": 1.1},
+ {"attribute":"customerLongitude", "attribute_location": "customerLongitude", "value": 2.2}
+ ],
+ "serviceName": "vCPE",
+ "policyScope": ["vCPE", "US", "INTERNATIONAL", "ip", "vGMuxInfra", "vG", "optimizationQueryPolicy"],
+ "policyType": "optimizationQueryPolicy"
+ }
+}
Distance_vG_1.json
Placement_Optimization_1.json
QueryPolicy_vCPE.json
+QueryPolicy_vCPE_2.json
hpa_policy_vGMuxInfra_1.json
hpa_policy_vG_1.json
vnfPolicy_vG.json
self.request_json = json_from_file(parameter_data_file)
self.policies = [json_from_file(policy_data_path + '/' + name) for name in valid_policies_files]
-
def test_conductor_api_call_builder(self):
main_dir = self.main_dir
conductor_api_template = main_dir + "osdf/templates/conductor_interface.json" # "osdf/templates/conductor_interface.json"
--- /dev/null
+# -------------------------------------------------------------------------
+# Copyright (c) 2017-2018 AT&T Intellectual Property
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# -------------------------------------------------------------------------
+#
+import json
+import unittest
+
+from osdf.adapters.policy.interface import get_policies
+from osdf.utils.interfaces import json_from_file
+from mock import patch
+
+
+class TestGetPolicy(unittest.TestCase):
+
+ def setUp(self):
+ main_dir = ""
+ parameter_data_file = main_dir + "test/placement-tests/request.json" # "test/placement-tests/request.json"
+ self.request_json = json_from_file(parameter_data_file)
+
+ def test_get_policy_function(self):
+ with patch('osdf.adapters.policy.interface.remote_api', return_value=[{"x: y"}]):
+ policy_list = get_policies(self.request_json, "placement")
+ policy_exist = True if len(policy_list) > 0 else False
+ self.assertEqual(policy_exist, True)