Add fields selector for API with query parameters INF-300 88/9388/1
authorZhang Rong(Jon) <rong.zhang@windriver.com>
Tue, 25 Oct 2022 03:01:55 +0000 (11:01 +0800)
committerZhang Rong(Jon) <rong.zhang@windriver.com>
Tue, 25 Oct 2022 03:01:55 +0000 (11:01 +0800)
Issue-ID: INF-300
Signed-off-by: Zhang Rong(Jon) <rong.zhang@windriver.com>
Change-Id: I4be68e71e685c77c570d4e605167294970e16888

o2app/bootstrap.py
o2app/entrypoints/flask_application.py
o2common/views/pagination_route.py
o2common/views/route.py [new file with mode: 0644]
o2ims/views/alarm_route.py
o2ims/views/api_ns.py
o2ims/views/ocloud_dto.py
o2ims/views/ocloud_route.py

index 228b240..e025a90 100644 (file)
@@ -21,7 +21,6 @@ from o2common.adapter.notifications import AbstractNotifications,\
 from o2common.adapter import redis_eventpublisher
 from o2common.service import unit_of_work
 from o2common.service import messagebus
-from o2common.config import config
 
 from o2app.service import handlers
 from o2app.adapter.unit_of_work import SqlAlchemyUnitOfWork
@@ -29,8 +28,6 @@ from o2app.adapter.unit_of_work import SqlAlchemyUnitOfWork
 from o2ims.adapter import orm as o2ims_orm
 from o2dms.adapter import orm as o2dms_orm
 
-from o2ims.adapter.clients import alarm_dict_client
-
 
 from o2common.helper import o2logging
 logger = o2logging.get_logger(__name__)
index f74dca2..53e7e19 100644 (file)
@@ -48,6 +48,8 @@ if auth:
     app.wsgi_app = authmiddleware.authmiddleware(app.wsgi_app)
 
 app.config.SWAGGER_UI_DOC_EXPANSION = 'list'
+# app.config['RESTX_MASK_HEADER'] = 'fields'
+app.config['RESTX_MASK_SWAGGER'] = False
 api = Api(app, version='1.0.0',
           title='INF O2 Services API',
           description='Swagger OpenAPI document for the INF O2 Services',
index e7b738f..c595d9f 100644 (file)
@@ -37,7 +37,6 @@ def link_header(full_path: str, ret):
         '&') if q.split('=')[0] != PAGE_PARAM])
     if query != '':
         query = query + '&'
-    logger.warning(query)
 
     link_list = []
     if (page_current > 1):
diff --git a/o2common/views/route.py b/o2common/views/route.py
new file mode 100644 (file)
index 0000000..b2d537d
--- /dev/null
@@ -0,0 +1,233 @@
+# Copyright (C) 2021-2022 Wind River Systems, Inc.
+#
+#  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.
+
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+# from collections import OrderedDict
+from functools import wraps
+# from six import iteritems
+
+from flask import request
+
+from flask_restx import Namespace
+from flask_restx._http import HTTPStatus
+from flask_restx.marshalling import marshal_with, marshal
+from flask_restx.utils import merge
+from flask_restx.mask import Mask  # , apply as apply_mask
+from flask_restx.model import Model
+from flask_restx.fields import List, Nested, String
+from flask_restx.utils import unpack
+
+from o2common.helper import o2logging
+logger = o2logging.get_logger(__name__)
+
+
+class O2Namespace(Namespace):
+
+    def __init__(self, name, description=None, path=None, decorators=None,
+                 validate=None, authorizations=None, ordered=False, **kwargs):
+        super().__init__(name, description, path, decorators,
+                         validate, authorizations, ordered, **kwargs)
+
+    def marshal_with(
+        self, fields, as_list=False, code=HTTPStatus.OK, description=None,
+        **kwargs
+    ):
+        """
+        A decorator specifying the fields to use for serialization.
+
+        :param bool as_list: Indicate that the return type is a list \
+            (for the documentation)
+        :param int code: Optionally give the expected HTTP response \
+            code if its different from 200
+
+        """
+
+        def wrapper(func):
+            doc = {
+                "responses": {
+                    str(code): (description, [fields], kwargs)
+                    if as_list
+                    else (description, fields, kwargs)
+                },
+                "__mask__": kwargs.get(
+                    "mask", True
+                ),  # Mask values can't be determined outside app context
+            }
+            func.__apidoc__ = merge(getattr(func, "__apidoc__", {}), doc)
+            return o2_marshal_with(fields, ordered=self.ordered,
+                                   **kwargs)(func)
+
+        return wrapper
+
+
+class o2_marshal_with(marshal_with):
+    def __init__(
+        self, fields, envelope=None, skip_none=False, mask=None, ordered=False
+    ):
+        """
+        :param fields: a dict of whose keys will make up the final
+                       serialized response output
+        :param envelope: optional key that will be used to envelop the
+                       serialized response
+        """
+        self.fields = fields
+        self.envelope = envelope
+        self.skip_none = skip_none
+        self.ordered = ordered
+        self.mask = Mask(mask, skip=True)
+
+    def __call__(self, f):
+        @wraps(f)
+        def wrapper(*args, **kwargs):
+            resp = f(*args, **kwargs)
+
+            req_args = request.args
+            mask = self._gen_mask_from_filter(**req_args)
+
+            # mask = self.mask
+
+            # if has_request_context():
+            # mask_header = current_app.config["RESTX_MASK_HEADER"]
+            # mask = request.headers.get(mask_header) or mask
+            if isinstance(resp, tuple):
+                data, code, headers = unpack(resp)
+                return (
+                    marshal(
+                        data,
+                        self.fields,
+                        self.envelope,
+                        self.skip_none,
+                        mask,
+                        self.ordered,
+                    ),
+                    code,
+                    headers,
+                )
+            else:
+                return marshal(
+                    resp, self.fields, self.envelope, self.skip_none, mask,
+                    self.ordered
+                )
+
+        return wrapper
+
+    def _gen_mask_from_filter(self, **kwargs) -> str:
+        mask_val = ''
+        if 'all_fields' in kwargs:
+            all_fields_without_space = kwargs['all_fields'].replace(" ", "")
+            all_fields = all_fields_without_space.lower()
+            if 'true' == all_fields:
+                mask_val = ''
+
+        elif 'fields' in kwargs and kwargs['fields'] != '':
+            fields_without_space = kwargs['fields'].replace(" ", "")
+
+            # filters = fields_without_space.split(',')
+
+            # mask_val_list = []
+            # for f in filters:
+            #     if '/' in f:
+            #         a = self.__gen_mask_tree(f)
+            #         mask_val_list.append(a)
+            #         continue
+            #     mask_val_list.append(f)
+            # mask_val = '{%s}' % ','.join(mask_val_list)
+            default_fields = {}
+
+            self.__update_filter_value(
+                default_fields, fields_without_space, True)
+
+            mask_val = self.__gen_mask_from_filter_tree(default_fields)
+
+        elif 'exclude_fields' in kwargs and kwargs['exclude_fields'] != '':
+            exclude_fields_without_space = kwargs['exclude_fields'].replace(
+                " ", "")
+
+            default_fields = self.__gen_filter_tree_from_model_with_value(
+                self.fields)
+
+            self.__update_filter_value(
+                default_fields, exclude_fields_without_space, False)
+
+            mask_val = self.__gen_mask_from_filter_tree(default_fields)
+        elif 'exclude_default' in kwargs and kwargs['exclude_default'] != '':
+            exclude_default_without_space = kwargs['exclude_default'].replace(
+                " ", "")
+            exclude_default = exclude_default_without_space.lower()
+            if 'true' == exclude_default:
+                mask_val = '{}'
+
+        else:
+            mask_val = ''
+
+        return mask_val
+
+    def __gen_mask_tree(self, field: str) -> str:
+
+        f = field.split('/', 1)
+        if len(f) > 1:
+            s = self.__gen_mask_tree(f[1])
+            return '%s%s' % (f[0], s)
+        else:
+            return '{%s}' % f[0]
+
+    def __gen_filter_tree_from_model_with_value(
+            self, model: Model, default_val: bool = True) -> dict:
+        filter = dict()
+        for i in model:
+            if type(model[i]) is List:
+                if type(model[i].container) is String:
+                    filter[i] = default_val
+                    continue
+                filter[i] = self.__gen_filter_tree_from_model_with_value(
+                    model[i].container.model, default_val)
+                continue
+            elif type(model[i]) is Nested:
+                filter[i] = self.__gen_filter_tree_from_model_with_value(
+                    model[i].model, default_val)
+            filter[i] = default_val
+        return filter
+
+    def __update_filter_value(self, default_fields: dict, filter: str,
+                              val: bool):
+        fields = filter.split(',')
+        for f in fields:
+            if '/' in f:
+                self.__update_filter_tree_value(default_fields, f, val)
+                continue
+            default_fields[f] = val
+
+    def __update_filter_tree_value(self, m: dict, filter: str, val: bool):
+        filter_list = filter.split('/', 1)
+        if filter_list[0] not in m:
+            m[filter_list[0]] = dict()
+        if len(filter_list) > 1:
+            self.__update_filter_tree_value(
+                m[filter_list[0]], filter_list[1], val)
+            return
+        m[filter_list[0]] = val
+
+    def __gen_mask_from_filter_tree(self, fields: dict) -> str:
+        mask_li = list()
+        for k, v in fields.items():
+            if type(v) is dict:
+                s = self.__gen_mask_from_filter_tree(v)
+                mask_li.append('%s%s' % (k, s))
+                continue
+            if v:
+                mask_li.append(k)
+
+        return '{%s}' % ','.join(mask_li)
index 6b32eee..28bfd5c 100644 (file)
@@ -37,6 +37,27 @@ def configure_api_route():
                          'Page number of the results to fetch.' +
                          ' Default: 1',
                          _in='query', default=1)
+@api_monitoring_v1.param(
+    'all_fields',
+    'Set any value for show all fields. This value will cover "fields" ' +
+    'and "all_fields".',
+    _in='query')
+@api_monitoring_v1.param(
+    'fields',
+    'Set fields to show, split by comman, "/" for parent and children.' +
+    ' Like "name,parent/children". This value will cover' +
+    ' "exculde_fields".',
+    _in='query')
+@api_monitoring_v1.param(
+    'exclude_fields',
+    'Set fields to exclude showing, split by comman, "/" for parent and ' +
+    'children. Like "name,parent/children". This value will cover ' +
+    '"exclude_default".',
+    _in='query')
+@api_monitoring_v1.param(
+    'exclude_default',
+    'Exclude showing all default fields, Set "true" to enable.',
+    _in='query')
 class AlarmListRouter(Resource):
 
     model = AlarmDTO.alarm_event_record_get
@@ -57,6 +78,27 @@ class AlarmListRouter(Resource):
 @api_monitoring_v1.route("/alarms/<alarmEventRecordId>")
 @api_monitoring_v1.param('alarmEventRecordId', 'ID of the alarm event record')
 @api_monitoring_v1.response(404, 'Alarm Event Record not found')
+@api_monitoring_v1.param(
+    'all_fields',
+    'Set any value for show all fields. This value will cover "fields" ' +
+    'and "all_fields".',
+    _in='query')
+@api_monitoring_v1.param(
+    'fields',
+    'Set fields to show, split by comman, "/" for parent and children.' +
+    ' Like "name,parent/children". This value will cover' +
+    ' "exculde_fields".',
+    _in='query')
+@api_monitoring_v1.param(
+    'exclude_fields',
+    'Set fields to exclude showing, split by comman, "/" for parent and ' +
+    'children. Like "name,parent/children". This value will cover ' +
+    '"exclude_default".',
+    _in='query')
+@api_monitoring_v1.param(
+    'exclude_default',
+    'Exclude showing all default fields, Set "true" to enable.',
+    _in='query')
 class AlarmGetRouter(Resource):
 
     model = AlarmDTO.alarm_event_record_get
@@ -81,6 +123,31 @@ class SubscriptionsListRouter(Resource):
 
     @api_monitoring_v1.doc('List alarm subscriptions')
     @api_monitoring_v1.marshal_list_with(model)
+    @api_monitoring_v1.param(
+        PAGE_PARAM,
+        'Page number of the results to fetch. Default: 1',
+        _in='query', default=1)
+    @api_monitoring_v1.param(
+        'all_fields',
+        'Set any value for show all fields. This value will cover "fields" ' +
+        'and "all_fields".',
+        _in='query')
+    @api_monitoring_v1.param(
+        'fields',
+        'Set fields to show, split by comman, "/" for parent and children.' +
+        ' Like "name,parent/children". This value will cover' +
+        ' "exculde_fields".',
+        _in='query')
+    @api_monitoring_v1.param(
+        'exclude_fields',
+        'Set fields to exclude showing, split by comman, "/" for parent and ' +
+        'children. Like "name,parent/children". This value will cover ' +
+        '"exclude_default".',
+        _in='query')
+    @api_monitoring_v1.param(
+        'exclude_default',
+        'Exclude showing all default fields, Set "true" to enable.',
+        _in='query')
     def get(self):
         parser = reqparse.RequestParser()
         parser.add_argument(PAGE_PARAM, location='args')
@@ -110,6 +177,27 @@ class SubscriptionGetDelRouter(Resource):
 
     @api_monitoring_v1.doc('Get Alarm Subscription by ID')
     @api_monitoring_v1.marshal_with(model)
+    @api_monitoring_v1.param(
+        'all_fields',
+        'Set any value for show all fields. This value will cover "fields" ' +
+        'and "all_fields".',
+        _in='query')
+    @api_monitoring_v1.param(
+        'fields',
+        'Set fields to show, split by comman, "/" for parent and children.' +
+        ' Like "name,parent/children". This value will cover' +
+        ' "exculde_fields".',
+        _in='query')
+    @api_monitoring_v1.param(
+        'exclude_fields',
+        'Set fields to exclude showing, split by comman, "/" for parent and ' +
+        'children. Like "name,parent/children". This value will cover ' +
+        '"exclude_default".',
+        _in='query')
+    @api_monitoring_v1.param(
+        'exclude_default',
+        'Exclude showing all default fields, Set "true" to enable.',
+        _in='query')
     def get(self, alarmSubscriptionID):
         result = alarm_view.subscription_one(
             alarmSubscriptionID, bus.uow)
index 3fbdc18..b06cb2a 100644 (file)
@@ -1,14 +1,28 @@
-from flask_restx import Namespace
+# Copyright (C) 2021-2022 Wind River Systems, Inc.
+#
+#  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.
 
+from o2common.views.route import O2Namespace
 
-api_ims_inventory_v1 = Namespace(
+
+api_ims_inventory_v1 = O2Namespace(
     "O2IMS_Inventory",
     description='IMS Inventory related operations.')
 
-api_provision_v1 = Namespace(
+api_provision_v1 = O2Namespace(
     "PROVISION",
     description='Provision related operations.')
 
-api_monitoring_v1 = Namespace(
+api_monitoring_v1 = O2Namespace(
     "O2IMS_InfrastructureMonitoring",
     description='O2 IMS Monitoring related operations.')
index c8e5202..df8385a 100644 (file)
@@ -75,46 +75,6 @@ class ResourceDTO:
         }
     )
 
-    list_result = api_ims_inventory_v1.model(
-        "ResourceListPagenationDto",
-        {
-            'count': fields.Integer(),
-            'page_num': fields.Integer(),
-            'results': fields.List(fields.Nested(resource_list))
-        }
-    )
-
-    # def get_paginated_list(results, url, start, limit):
-    #     start = int(start)
-    #     limit = int(limit)
-    #     count = len(results)
-    #     if count < start or limit < 0:
-    #         api_ims_inventory_v1.abort(404)
-    #     # make response
-    #     obj = {}
-    #     obj['start'] = start
-    #     obj['limit'] = limit
-    #     obj['count'] = count
-    #     # make URLs
-    #     # make previous url
-    #     if start == 1:
-    #         obj['previous'] = ''
-    #     else:
-    #         start_copy = max(1, start - limit)
-    #         limit_copy = start - 1
-    #         obj['previous'] = url + \
-    #             '?start=%d&limit=%d' % (start_copy, limit_copy)
-    #     # make next url
-    #     if start + limit > count:
-    #         obj['next'] = ''
-    #     else:
-    #         start_copy = start + limit
-    #         obj['next'] = url + '?start=%d&limit=%d' % (start_copy, limit)
-    #     # finally extract result according to bounds
-    #     # obj['results'] = results[(start - 1):(start - 1 + limit)]
-    #     obj['result'] = fields.List(fields.Nested(ResourceDTO.resource_list))
-    #     return obj
-
     def recursive_resource_mapping(iteration_number=2):
         resource_json_mapping = {
             'resourceId': fields.String(required=True,
index 5feb6b8..43a4761 100644 (file)
@@ -35,6 +35,26 @@ def configure_api_route():
 # ----------  OClouds ---------- #
 @api_ims_inventory_v1.route("/")
 @api_ims_inventory_v1.response(404, 'oCloud not found')
+@api_ims_inventory_v1.param(
+    'all_fields',
+    'Set any value for show all fields. This value will cover "fields" ' +
+    'and "all_fields".',
+    _in='query')
+@api_ims_inventory_v1.param(
+    'fields',
+    'Set fields to show, split by comman, "/" for parent and children.' +
+    ' Like "name,parent/children". This value will cover "exculde_fields".',
+    _in='query')
+@api_ims_inventory_v1.param(
+    'exclude_fields',
+    'Set fields to exclude showing, split by comman, "/" for parent and ' +
+    'children. Like "name,parent/children". This value will cover ' +
+    '"exclude_default".',
+    _in='query')
+@api_ims_inventory_v1.param(
+    'exclude_default',
+    'Exclude showing all default fields, Set "true" to enable.',
+    _in='query')
 class OcloudsListRouter(Resource):
     """Ocloud get endpoint
     O2 interface ocloud endpoint
@@ -57,6 +77,26 @@ class OcloudsListRouter(Resource):
                             'Page number of the results to fetch.' +
                             ' Default: 1',
                             _in='query', default=1)
+@api_ims_inventory_v1.param(
+    'all_fields',
+    'Set any value for show all fields. This value will cover "fields" ' +
+    'and "all_fields".',
+    _in='query')
+@api_ims_inventory_v1.param(
+    'fields',
+    'Set fields to show, split by comman, "/" for parent and children.' +
+    ' Like "name,parent/children". This value will cover "exculde_fields".',
+    _in='query')
+@api_ims_inventory_v1.param(
+    'exclude_fields',
+    'Set fields to exclude showing, split by comman, "/" for parent and ' +
+    'children. Like "name,parent/children". This value will cover ' +
+    '"exclude_default".',
+    _in='query')
+@api_ims_inventory_v1.param(
+    'exclude_default',
+    'Exclude showing all default fields, Set "true" to enable.',
+    _in='query')
 class ResourceTypesListRouter(Resource):
 
     model = ResourceTypeDTO.resource_type_get
@@ -77,6 +117,26 @@ class ResourceTypesListRouter(Resource):
 @api_ims_inventory_v1.route("/resourceTypes/<resourceTypeID>")
 @api_ims_inventory_v1.param('resourceTypeID', 'ID of the resource type')
 @api_ims_inventory_v1.response(404, 'Resource type not found')
+@api_ims_inventory_v1.param(
+    'all_fields',
+    'Set any value for show all fields. This value will cover "fields" ' +
+    'and "all_fields".',
+    _in='query')
+@api_ims_inventory_v1.param(
+    'fields',
+    'Set fields to show, split by comman, "/" for parent and children.' +
+    ' Like "name,parent/children". This value will cover "exculde_fields".',
+    _in='query')
+@api_ims_inventory_v1.param(
+    'exclude_fields',
+    'Set fields to exclude showing, split by comman, "/" for parent and ' +
+    'children. Like "name,parent/children". This value will cover ' +
+    '"exclude_default".',
+    _in='query')
+@api_ims_inventory_v1.param(
+    'exclude_default',
+    'Exclude showing all default fields, Set "true" to enable.',
+    _in='query')
 class ResourceTypeGetRouter(Resource):
 
     model = ResourceTypeDTO.resource_type_get
@@ -97,6 +157,26 @@ class ResourceTypeGetRouter(Resource):
                             'Page number of the results to fetch.' +
                             ' Default: 1',
                             _in='query', default=1)
+@api_ims_inventory_v1.param(
+    'all_fields',
+    'Set any value for show all fields. This value will cover "fields" ' +
+    'and "all_fields".',
+    _in='query')
+@api_ims_inventory_v1.param(
+    'fields',
+    'Set fields to show, split by comman, "/" for parent and children.' +
+    ' Like "name,parent/children". This value will cover "exculde_fields".',
+    _in='query')
+@api_ims_inventory_v1.param(
+    'exclude_fields',
+    'Set fields to exclude showing, split by comman, "/" for parent and ' +
+    'children. Like "name,parent/children". This value will cover ' +
+    '"exclude_default".',
+    _in='query')
+@api_ims_inventory_v1.param(
+    'exclude_default',
+    'Exclude showing all default fields, Set "true" to enable.',
+    _in='query')
 class ResourcePoolsListRouter(Resource):
 
     model = ResourcePoolDTO.resource_pool_get
@@ -117,6 +197,26 @@ class ResourcePoolsListRouter(Resource):
 @api_ims_inventory_v1.route("/resourcePools/<resourcePoolID>")
 @api_ims_inventory_v1.param('resourcePoolID', 'ID of the resource pool')
 @api_ims_inventory_v1.response(404, 'Resource pool not found')
+@api_ims_inventory_v1.param(
+    'all_fields',
+    'Set any value for show all fields. This value will cover "fields" ' +
+    'and "all_fields".',
+    _in='query')
+@api_ims_inventory_v1.param(
+    'fields',
+    'Set fields to show, split by comman, "/" for parent and children.' +
+    ' Like "name,parent/children". This value will cover "exculde_fields".',
+    _in='query')
+@api_ims_inventory_v1.param(
+    'exclude_fields',
+    'Set fields to exclude showing, split by comman, "/" for parent and ' +
+    'children. Like "name,parent/children". This value will cover ' +
+    '"exclude_default".',
+    _in='query')
+@api_ims_inventory_v1.param(
+    'exclude_default',
+    'Exclude showing all default fields, Set "true" to enable.',
+    _in='query')
 class ResourcePoolGetRouter(Resource):
 
     model = ResourcePoolDTO.resource_pool_get
@@ -147,6 +247,26 @@ class ResourcePoolGetRouter(Resource):
                             'Page number of the results to fetch.' +
                             ' Default: 1',
                             _in='query', default=1)
+@api_ims_inventory_v1.param(
+    'all_fields',
+    'Set any value for show all fields. This value will cover "fields" ' +
+    'and "all_fields".',
+    _in='query')
+@api_ims_inventory_v1.param(
+    'fields',
+    'Set fields to show, split by comman, "/" for parent and children.' +
+    ' Like "name,parent/children". This value will cover "exculde_fields".',
+    _in='query')
+@api_ims_inventory_v1.param(
+    'exclude_fields',
+    'Set fields to exclude showing, split by comman, "/" for parent and ' +
+    'children. Like "name,parent/children". This value will cover ' +
+    '"exclude_default".',
+    _in='query')
+@api_ims_inventory_v1.param(
+    'exclude_default',
+    'Exclude showing all default fields, Set "true" to enable.',
+    _in='query')
 class ResourcesListRouter(Resource):
 
     model = ResourceDTO.resource_list
@@ -156,8 +276,6 @@ class ResourcesListRouter(Resource):
         parser = reqparse.RequestParser()
         parser.add_argument('resourceTypeName', location='args')
         parser.add_argument('parentId', location='args')
-        # parser.add_argument('sort', location='args')
-        # parser.add_argument('per_page', location='args')
         parser.add_argument(PAGE_PARAM, location='args')
         args = parser.parse_args()
         kwargs = {}
@@ -174,7 +292,6 @@ class ResourcesListRouter(Resource):
             kwargs['page'] = args.nextpage_opaque_marker
 
         ret = ocloud_view.resources(resourcePoolID, bus.uow, **kwargs)
-
         return link_header(request.full_path, ret)
 
 
@@ -183,6 +300,26 @@ class ResourcesListRouter(Resource):
 @api_ims_inventory_v1.param('resourcePoolID', 'ID of the resource pool')
 @api_ims_inventory_v1.param('resourceID', 'ID of the resource')
 @api_ims_inventory_v1.response(404, 'Resource not found')
+@api_ims_inventory_v1.param(
+    'all_fields',
+    'Set any value for show all fields. This value will cover "fields" ' +
+    'and "all_fields".',
+    _in='query')
+@api_ims_inventory_v1.param(
+    'fields',
+    'Set fields to show, split by comman, "/" for parent and children.' +
+    ' Like "name,parent/children". This value will cover "exculde_fields".',
+    _in='query')
+@api_ims_inventory_v1.param(
+    'exclude_fields',
+    'Set fields to exclude showing, split by comman, "/" for parent and ' +
+    'children. Like "name,parent/children". This value will cover ' +
+    '"exclude_default".',
+    _in='query')
+@api_ims_inventory_v1.param(
+    'exclude_default',
+    'Exclude showing all default fields, Set "true" to enable.',
+    _in='query')
 class ResourceGetRouter(Resource):
 
     # dto = ResourceDTO()
@@ -205,6 +342,26 @@ class ResourceGetRouter(Resource):
                             'Page number of the results to fetch.' +
                             ' Default: 1',
                             _in='query', default=1)
+@api_ims_inventory_v1.param(
+    'all_fields',
+    'Set any value for show all fields. This value will cover "fields" ' +
+    'and "all_fields".',
+    _in='query')
+@api_ims_inventory_v1.param(
+    'fields',
+    'Set fields to show, split by comman, "/" for parent and children.' +
+    ' Like "name,parent/children". This value will cover "exculde_fields".',
+    _in='query')
+@api_ims_inventory_v1.param(
+    'exclude_fields',
+    'Set fields to exclude showing, split by comman, "/" for parent and ' +
+    'children. Like "name,parent/children". This value will cover ' +
+    '"exclude_default".',
+    _in='query')
+@api_ims_inventory_v1.param(
+    'exclude_default',
+    'Exclude showing all default fields, Set "true" to enable.',
+    _in='query')
 class DeploymentManagersListRouter(Resource):
 
     model = DeploymentManagerDTO.deployment_manager_list
@@ -228,6 +385,26 @@ class DeploymentManagersListRouter(Resource):
 @api_ims_inventory_v1.param('profile', 'DMS profile: value supports "sol018"',
                             _in='query')
 @api_ims_inventory_v1.response(404, 'Deployment manager not found')
+@api_ims_inventory_v1.param(
+    'all_fields',
+    'Set any value for show all fields. This value will cover "fields" ' +
+    'and "all_fields".',
+    _in='query')
+@api_ims_inventory_v1.param(
+    'fields',
+    'Set fields to show, split by comman, "/" for parent and children.' +
+    ' Like "name,parent/children". This value will cover "exculde_fields".',
+    _in='query')
+@api_ims_inventory_v1.param(
+    'exclude_fields',
+    'Set fields to exclude showing, split by comman, "/" for parent and ' +
+    'children. Like "name,parent/children". This value will cover ' +
+    '"exclude_default".',
+    _in='query')
+@api_ims_inventory_v1.param(
+    'exclude_default',
+    'Exclude showing all default fields, Set "true" to enable.',
+    _in='query')
 class DeploymentManagerGetRouter(Resource):
 
     model = DeploymentManagerDTO.deployment_manager_get
@@ -260,6 +437,31 @@ class SubscriptionsListRouter(Resource):
 
     @api_ims_inventory_v1.doc('List subscriptions')
     @api_ims_inventory_v1.marshal_list_with(model)
+    @api_ims_inventory_v1.param(
+        PAGE_PARAM,
+        'Page number of the results to fetch. Default: 1',
+        _in='query', default=1)
+    @api_ims_inventory_v1.param(
+        'all_fields',
+        'Set any value for show all fields. This value will cover "fields" ' +
+        'and "all_fields".',
+        _in='query')
+    @api_ims_inventory_v1.param(
+        'fields',
+        'Set fields to show, split by comman, "/" for parent and children.' +
+        ' Like "name,parent/children". This value will cover' +
+        ' "exculde_fields".',
+        _in='query')
+    @api_ims_inventory_v1.param(
+        'exclude_fields',
+        'Set fields to exclude showing, split by comman, "/" for parent and ' +
+        'children. Like "name,parent/children". This value will cover ' +
+        '"exclude_default".',
+        _in='query')
+    @api_ims_inventory_v1.param(
+        'exclude_default',
+        'Exclude showing all default fields, Set "true" to enable.',
+        _in='query')
     def get(self):
         parser = reqparse.RequestParser()
         parser.add_argument(PAGE_PARAM, location='args')
@@ -289,6 +491,27 @@ class SubscriptionGetDelRouter(Resource):
 
     @api_ims_inventory_v1.doc('Get subscription by ID')
     @api_ims_inventory_v1.marshal_with(model)
+    @api_ims_inventory_v1.param(
+        'all_fields',
+        'Set any value for show all fields. This value will cover "fields" ' +
+        'and "all_fields".',
+        _in='query')
+    @api_ims_inventory_v1.param(
+        'fields',
+        'Set fields to show, split by comman, "/" for parent and children.' +
+        ' Like "name,parent/children". This value will cover' +
+        ' "exculde_fields".',
+        _in='query')
+    @api_ims_inventory_v1.param(
+        'exclude_fields',
+        'Set fields to exclude showing, split by comman, "/" for parent and ' +
+        'children. Like "name,parent/children". This value will cover ' +
+        '"exclude_default".',
+        _in='query')
+    @api_ims_inventory_v1.param(
+        'exclude_default',
+        'Exclude showing all default fields, Set "true" to enable.',
+        _in='query')
     def get(self, subscriptionID):
         result = ocloud_view.subscription_one(
             subscriptionID, bus.uow)