HewlettPackard / oneview-sdk-ruby

This project is no longer being developed and has limited support. In the near future this repository will be fully deprecated. Please consider using other OneView projects, such as Golang and Python.
Apache License 2.0
12 stars 16 forks source link

Structure for API 500 Support #199

Closed aalexmonteiro closed 7 years ago

aalexmonteiro commented 7 years ago

Scenario/Intent

It is necessary to create structure for api500 support for class development, unit tests, integration tests and examples.

Environment Details

Expected Result

Ready for development of the API 500.

Actual Result

The current version of the Ruby SDK does not have the necessary structure for development of the API 500.

aalexmonteiro commented 7 years ago

@tmiotto , @fgbulsoni , @jsmartt

I am implementing the necessary changes to the API500 development.

When I went to create api500.rb, I realized that the implementation was pretty much the same. I thought on the use of include or extends to avoid code duplicated.

Talking with @ricardogpsf , we saw a solution that can to be interesting for API500 development and future versions.

See the code below with the comments, please!

# Creating the modules API300 and API500
module OneviewSDK
  module API300
    # something implemented
  end  
end

module OneviewSDK
  module API500
    include OneviewSDK::API300

  end  
end

# Creating the module C7000
module OneviewSDK
  module API300
    module C7000
      # something implemented
    end
  end  
end

module OneviewSDK
  module API500
    include OneviewSDK::API300
  end  
end

# Creating the class Switch for API 300 C7000
module OneviewSDK
  module API300
    module C7000
      class Switch
        def method
          puts 'method on API300 Switch'
        end

        def method_2
          puts 'method 2 on API300 Switch'
        end

        def self.class_method
          puts 'class method on API300 Switch'
        end
      end
    end
  end  
end

# Creating the class LogicalSwitch for API 300 C7000
module OneviewSDK
  module API300
    module C7000
      class LogicalSwitch
        def method
          puts 'method on API300 LogicalSwitch'
        end

        def self.class_method
          puts 'class method on API300 LogicalSwitch'
        end
      end
    end
  end  
end

# Creating the class Switch for API 500 C7000
module OneviewSDK
  module API500
    module C7000
      include OneviewSDK::API300::C7000
      class Switch  < OneviewSDK::API300::C7000::Switch
        def method
          puts 'method on API500 Switch'
        end

        def self.class_method
          puts 'class method on API500 Switch'
        end
      end
    end
  end  
end

puts 'Running example for API300 Logical Switch'
ls300 = OneviewSDK::API300::C7000::LogicalSwitch.new
ls300.method                                                                      # puts "method on API300 LogicalSwitch"
OneviewSDK::API300::C7000::LogicalSwitch.class_method # puts class method on API300 LogicalSwitch 

puts "\nRunning example for API500 Logical Switch"
ls500 = OneviewSDK::API500::C7000::LogicalSwitch.new
ls500.method                                                                      # method on API300 LogicalSwitch
OneviewSDK::API500::C7000::LogicalSwitch.class_method # puts class method on API300 LogicalSwitch

puts "\nRunning example for API300 Switch"
sw300 = OneviewSDK::API300::C7000::Switch.new
sw300.method                                                          # puts method on API300 Switch
sw300.method_2                                                      # method 2 on API300 Switch
OneviewSDK::API300::C7000::Switch.class_method # puts class method on API300 Switch

puts "\nRunning example for API500 Switch"
sw500 = OneviewSDK::API500::C7000::Switch.new
sw500.method                                                         # puts method on API500 Switch
sw500.method_2                                                     # puts method_2 on API300 Switch
OneviewSDK::API500::C7000::Switch.class_method # puts class method on API500 Switch

Explanations:

  1. On the class OneviewSDK::API500::C7000::Switch, was mande the include of the module OneviewSDK::API300::C7000. This way it has been implemented the override only for the methods that need to be reimplement.

  2. It wasn't necessary to create the class for LogicalSwitch for API500, because was made the include OneviewSDK::API300 on the module Oneview::SDK::API500. This way we will create fewer classes and files, being only is necessary create the classes with some particularity and decreasing the amount of written code.

I hope I have been clear with my explanations.

Ricardo and I, we would like to know what you think about it and if we are not crazy. ha ha ha

jsmartt commented 7 years ago

I think it's definitely a great idea, as long as we're able to do it. API300 implements most (if not all) of the API200 resources, and it's fine if the including module supports all the resources of the included module, but if API300 supports a resource that no longer exists in API500, then you'd be in trouble. So as long as we're adding resources, not needing to subtract any.

The only other concerns I can foresee would be code comments (YARD docs) & log/print statement references to the API module name getting included with the wrong API module name. I guess we'd have to make the ones we want to include generic.

fgbulsoni commented 7 years ago

At a first look, I'm guessing this will also bring problems to the RDoc auto-generated documentation, as the classes which 'have not been implemented, just included' would not appear on the docs. (Correct me if this is wrong) Plus, in the example, running a:

OneviewSDK::API500::LogicalSwitch.new(client, data)

would actually generate an instance of <OneviewSDK::API300::LogicalSwitch>. If I recall, this was one of the things we pointed as downsides when discussing the use of includes for the restructuring of the SDK from API200 to API300 and sort of decided to stay away from it, despite the additional files that had to be created for that. Not sure how I feel about it at the moment, but I still don't like the idea of generating an instance of a type that I do not expect. P.S. this would likely also present some challenge when running unit tests with expectations.

aalexmonteiro commented 7 years ago

I get it, guys. For this reason, we have decided to know your opinions. So I'm going to create something similar in API500, like it was for API300. Thanks!