Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generic Objects Subcollection #57

Merged
merged 2 commits into from
Oct 3, 2017
Merged

Generic Objects Subcollection #57

merged 2 commits into from
Oct 3, 2017

Conversation

jntullo
Copy link

@jntullo jntullo commented Sep 18, 2017

This PR adds a Generic Objects Subcollection on the Generic Object Definition

Usage

GET /api/generic_object_definitions/:id/generic_objects

will return the collection of generic objects of that definition type:

{
  "name"      :"generic_objects",
  "count"     :2,
  "subcount"  :2,
  "resources" :[
   { "href" : "api/generic_object_definitions/:id/generic_objects/:id" },
   { "href" : "api/generic_object_definitions/:id/generic_objects/:id" },
  ]
}

GET /api/generic_object_definitions/:id/generic_objects/:id

will return property attributes by default:

{
  "href"                : "/api/generic_object_definitions/:id/generic_objects/:id",
  "id"                  : "1000000001",
  "name"                : "bar",
  ... 
  "property_attributes" : { "is_something" : true }
}

can specify associations on the request, ie:
GET /api/generic_object_definitions/:id/generic_objects/:id?associations=vms,services
returns:

{
  "href"                : "api/generic_object_definitions/:id/generic_objects/:id",
  "id"                  : "10000001",
  "name"                : "bar",
  "property_attributes" : { "is_something" : true },
  "vms"                 : [{ "id": "<vm id>" ...}],
  "services"            : [{"id": "<service id>"...}]
}

GET /api/services/:id/generic_objects

  • Returns the generic objects associated with a service

GET /api/services/:id?expand=resources,generic_objects&attributes=generic_objects.generic_object_definition

  • will return the service as well as the generic objects with associated generic object definition:
{'name':'services',
 'count':1,
 'subcount':1,
 'resources':
   [{'href':'/api/services/:id',
     'id':':id',
     'name':'svc',
     ...
     'generic_objects':
       [{
         'id':':id',
         'name':'generic_object_0000000000001',
         ...
         'generic_object_definition' : {
            'id' : ':id',
            'name' : 'generic_object_definition_name'
            ...
          }
        }
       ]
    }
   ]
}

POST /api/generic_object_definitions/:id/generic_objects

it can create a new generic object for the specified generic object definition:

{
  "name"                : "go_name1",
  "uid"                 : "optional_uid",
  "property_attributes" : {
    "widget" : "widget value",
  },
  "associations"        : {
    "vms" : [
      { "href" : "/api/vms/:id" },
    ]
  }
}

Background

There is shared code between the generic objects controller and the generic objects subcollection. The code is tightly coupled with the controllers, and therefore not suitable for a service, which was the design choice behind the mixin.

When writing the mixin, the initial intent was to not have it as a part of BaseController, it was instead to have Api::Mixins::GenericObjects, however, this caused sporadic test failures when included as include Mixins::GenericObjects. I think this may require greater refactoring to achieve it as Api::Mixins, which might be better suited in another PR.

@miq-bot miq-bot added the wip label Sep 18, 2017
},
'associations' => {
'vms' => [
{ 'href' => api_vm_url(nil, vm.id) },
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

with these helpers, you can simply pass in the object, i.e. api_vm_url(nil, vm)

get(api_generic_object_definition_generic_object_url(nil, object_def.id, object.id), :params => {:associations => 'vms'})

expected = {
'href' => api_generic_object_definition_generic_object_url(nil, object_def.id, object.id),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same comment throughout, with these helpers just the object so ...(nil, object_def, object)

module Subcollections
module GenericObjects
def generic_objects_query_resource(object_definition)
object_definition.generic_objects
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what if the generic object definition has no generic object, is this nil here ? what is returned by API ?

Copy link
Author

@jntullo jntullo Sep 19, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@abellotti if it has no generic objects, it just returns an empty array, so the api returns "resources": []

@@ -0,0 +1,40 @@
module Api
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if this should go in a new folder: app/controllers/api/mixins/
and dropping the BaseController in the module hierarchy, it would just be a submodule of the
class including the mixin.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@abellotti I explained a bit more in the PR description, but I have been looking into this (which is why it's still WIP) ...however, without the BaseController module hierarchy and with it in app/controllers/api/mixins, it has been creating sporadic test failures that I have been trying to figure out.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems to have to do with the way things are loaded, but haven't figured out the solution just yet.

@@ -114,6 +120,10 @@ def build_generic_object_definition_options

private

def generic_objects_request
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not quite sure what this does. why is it needed ?

Copy link
Author

@jntullo jntullo Sep 19, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know, it's a bit funky, but basically this controller needs to have the before_action hooks to allow for the subcollection to set the associations for requests such as GET /api/generic_object_definitions/:id/generic_objects?associations=vmsas well as to set the hook to set @additional_attributes...we don't want to set the hooks unless the subject is generic_objects, so this method is the if condition on the hook. updated the name to is_generic_objects_request. Any other naming ideas?

@jntullo
Copy link
Author

jntullo commented Sep 19, 2017

@abellotti exhibit A of sporadic test failures. Thought everything was fine with the mixin, finally, but Travis is now having failures I don't get locally 😭

@jntullo jntullo changed the title [WIP] Generic Objects Subcollection Generic Objects Subcollection Sep 19, 2017
@jntullo
Copy link
Author

jntullo commented Sep 19, 2017

@miq-bot assign @abellotti

@@ -1,5 +1,11 @@
module Api
class GenericObjectDefinitionsController < BaseController
include Api::Mixins::GenericObjects
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In short, I think you needed the Api qualification because the classic UI has a top-level Mixins namespace. If something in there gets loaded first, it will break the autoloading of this module. I'm proposing that the classic UI not do that and put their mixins in their own namespace.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks @imtayadeway !!! ✨

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or you could use include_concern Mixins::GenericObjects which I guess is the standard way that we deal with this problem (and may convey to the next person that there is some kind of contention over the Mixins namespace)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@imtayadeway unfortunately I tried this, and the API is not happy :(

@miq-bot
Copy link
Member

miq-bot commented Sep 21, 2017

This pull request is not mergeable. Please rebase and repush.

@bascar
Copy link

bascar commented Sep 29, 2017

@abellotti can we get this merged please? it is blocking other Generic Object items

@jntullo
Copy link
Author

jntullo commented Sep 29, 2017

just squashed some commits.

@abellotti
Copy link
Member

LGTM!!

@imtayadeway ?

@abellotti
Copy link
Member

ping @imtayadeway can we borrow your 👀 please ?

@miq-bot
Copy link
Member

miq-bot commented Oct 2, 2017

This pull request is not mergeable. Please rebase and repush.

return property attributes by default and return specified associations

move mixin to its own folder

move include from the sub collection to the collection
@miq-bot
Copy link
Member

miq-bot commented Oct 3, 2017

Checked commits jntullo/manageiq-api@27d50e2~...ff531b4 with ruby 2.2.6, rubocop 0.47.1, and haml-lint 0.20.0
9 files checked, 0 offenses detected
Everything looks fine. ⭐

let(:vm) { FactoryGirl.create(:vm_amazon) }

before do
object_def.add_property_attribute('is_something', 'boolean')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The extensive setup here seems to suggest that the GO API is missing something....perhaps we could at a later point create a factory, or a builder, or at least enhance the factory girl definition to help simplify this process?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, some factories for "simple" objects with dummy attributes would be useful

Copy link
Contributor

@imtayadeway imtayadeway left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 Chatted with @jntullo on gitter about some possible "might be nice" changes to get some of the details of serializing and building generic objects out of the controller, but nothing blocking for this PR. Thanks @jntullo ! 🎈

@abellotti
Copy link
Member

Thank you @imtayadeway for your review 🙇

@abellotti abellotti merged commit f122f18 into ManageIQ:master Oct 3, 2017
@abellotti abellotti added this to the Sprint 71 Ending Oct 16, 2017 milestone Oct 3, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants