miasma 0.3.2 → 0.3.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/CHANGELOG.md +4 -0
- data/LICENSE +1 -1
- data/README.md +5 -2
- data/lib/miasma.rb +14 -15
- data/lib/miasma/error.rb +17 -10
- data/lib/miasma/models.rb +9 -9
- data/lib/miasma/models/auto_scale.rb +5 -7
- data/lib/miasma/models/auto_scale/group.rb +8 -13
- data/lib/miasma/models/auto_scale/groups.rb +2 -4
- data/lib/miasma/models/block_storage.rb +1 -0
- data/lib/miasma/models/compute.rb +4 -6
- data/lib/miasma/models/compute/server.rb +5 -6
- data/lib/miasma/models/compute/servers.rb +2 -4
- data/lib/miasma/models/dns.rb +1 -0
- data/lib/miasma/models/load_balancer.rb +5 -7
- data/lib/miasma/models/load_balancer/balancer.rb +9 -11
- data/lib/miasma/models/load_balancer/balancers.rb +2 -4
- data/lib/miasma/models/monitoring.rb +1 -0
- data/lib/miasma/models/orchestration.rb +37 -7
- data/lib/miasma/models/orchestration/event.rb +2 -5
- data/lib/miasma/models/orchestration/events.rb +5 -7
- data/lib/miasma/models/orchestration/plan.rb +87 -0
- data/lib/miasma/models/orchestration/plans.rb +52 -0
- data/lib/miasma/models/orchestration/resource.rb +8 -10
- data/lib/miasma/models/orchestration/resources.rb +3 -5
- data/lib/miasma/models/orchestration/stack.rb +106 -20
- data/lib/miasma/models/orchestration/stacks.rb +3 -5
- data/lib/miasma/models/queues.rb +1 -0
- data/lib/miasma/models/queuing.rb +72 -0
- data/lib/miasma/models/queuing/queue.rb +77 -0
- data/lib/miasma/models/queuing/queues.rb +32 -0
- data/lib/miasma/models/storage.rb +8 -9
- data/lib/miasma/models/storage/bucket.rb +4 -7
- data/lib/miasma/models/storage/buckets.rb +2 -4
- data/lib/miasma/models/storage/file.rb +13 -16
- data/lib/miasma/models/storage/files.rb +3 -5
- data/lib/miasma/specs.rb +4 -4
- data/lib/miasma/specs/compute_abstract.rb +24 -33
- data/lib/miasma/specs/load_balancer_abstract.rb +17 -27
- data/lib/miasma/specs/orchestration_abstract.rb +26 -37
- data/lib/miasma/specs/storage_abstract.rb +21 -27
- data/lib/miasma/types.rb +6 -8
- data/lib/miasma/types/api.rb +28 -31
- data/lib/miasma/types/collection.rb +8 -10
- data/lib/miasma/types/data.rb +2 -5
- data/lib/miasma/types/model.rb +13 -16
- data/lib/miasma/types/thin_model.rb +7 -10
- data/lib/miasma/utils.rb +7 -7
- data/lib/miasma/utils/animal_strings.rb +1 -3
- data/lib/miasma/utils/api_methoding.rb +2 -5
- data/lib/miasma/utils/immutable.rb +2 -6
- data/lib/miasma/utils/lazy.rb +2 -2
- data/lib/miasma/utils/memoization.rb +1 -1
- data/lib/miasma/utils/smash.rb +1 -1
- data/lib/miasma/version.rb +1 -1
- data/miasma.gemspec +21 -19
- metadata +44 -12
| @@ -1,43 +1,39 @@ | |
| 1 | 
            -
            require  | 
| 1 | 
            +
            require "timeout"
         | 
| 2 2 |  | 
| 3 | 
            -
            MIASMA_ORCHESTRATION_ABSTRACT = ->{
         | 
| 3 | 
            +
            MIASMA_ORCHESTRATION_ABSTRACT = -> {
         | 
| 4 4 |  | 
| 5 5 | 
             
              # Required `let`s:
         | 
| 6 6 | 
             
              # * orchestration: orchestration API
         | 
| 7 7 | 
             
              # * build_args: stack build arguments [Smash]
         | 
| 8 8 |  | 
| 9 9 | 
             
              describe Miasma::Models::Orchestration, :vcr do
         | 
| 10 | 
            -
             | 
| 11 | 
            -
                it 'should provide #stacks collection' do
         | 
| 10 | 
            +
                it "should provide #stacks collection" do
         | 
| 12 11 | 
             
                  orchestration.stacks.must_be_kind_of Miasma::Models::Orchestration::Stacks
         | 
| 13 12 | 
             
                end
         | 
| 14 13 |  | 
| 15 14 | 
             
                describe Miasma::Models::Orchestration::Stacks do
         | 
| 16 | 
            -
             | 
| 17 | 
            -
                  it 'should provide instance class used within collection' do
         | 
| 15 | 
            +
                  it "should provide instance class used within collection" do
         | 
| 18 16 | 
             
                    orchestration.stacks.model.must_equal Miasma::Models::Orchestration::Stack
         | 
| 19 17 | 
             
                  end
         | 
| 20 18 |  | 
| 21 | 
            -
                  it  | 
| 19 | 
            +
                  it "should build new instance for collection" do
         | 
| 22 20 | 
             
                    instance = orchestration.stacks.build
         | 
| 23 21 | 
             
                    instance.must_be_kind_of Miasma::Models::Orchestration::Stack
         | 
| 24 22 | 
             
                  end
         | 
| 25 23 |  | 
| 26 | 
            -
                  it  | 
| 24 | 
            +
                  it "should provide #all stacks" do
         | 
| 27 25 | 
             
                    orchestration.stacks.all.must_be_kind_of Array
         | 
| 28 26 | 
             
                  end
         | 
| 29 | 
            -
             | 
| 30 27 | 
             
                end
         | 
| 31 28 |  | 
| 32 29 | 
             
                describe Miasma::Models::Orchestration::Stacks do
         | 
| 33 | 
            -
             | 
| 34 30 | 
             
                  before do
         | 
| 35 | 
            -
                    unless | 
| 36 | 
            -
                      VCR.use_cassette( | 
| 31 | 
            +
                    unless $miasma_stack
         | 
| 32 | 
            +
                      VCR.use_cassette("Miasma_Models_Orchestration_Global/GLOBAL_orchestration_stack_create") do
         | 
| 37 33 | 
             
                        @stack = orchestration.stacks.build(build_args)
         | 
| 38 34 | 
             
                        @stack.save
         | 
| 39 35 | 
             
                        Timeout.timeout(500) do
         | 
| 40 | 
            -
                          until | 
| 36 | 
            +
                          until @stack.state == :create_complete
         | 
| 41 37 | 
             
                            miasma_spec_sleep
         | 
| 42 38 | 
             
                            @stack.reload
         | 
| 43 39 | 
             
                          end
         | 
| @@ -47,7 +43,7 @@ MIASMA_ORCHESTRATION_ABSTRACT = ->{ | |
| 47 43 | 
             
                        $miasma_stack = @stack
         | 
| 48 44 | 
             
                      end
         | 
| 49 45 | 
             
                      Kernel.at_exit do
         | 
| 50 | 
            -
                        VCR.use_cassette( | 
| 46 | 
            +
                        VCR.use_cassette("Miasma_Models_Compute_Global/GLOBAL_orchestration_stack_destroy") do
         | 
| 51 47 | 
             
                          $miasma_stack.destroy
         | 
| 52 48 | 
             
                        end
         | 
| 53 49 | 
             
                      end
         | 
| @@ -57,55 +53,50 @@ MIASMA_ORCHESTRATION_ABSTRACT = ->{ | |
| 57 53 | 
             
                    @stack.reload
         | 
| 58 54 | 
             
                  end
         | 
| 59 55 |  | 
| 60 | 
            -
                  let(:stack){ @stack }
         | 
| 61 | 
            -
             | 
| 62 | 
            -
                  describe 'collection' do
         | 
| 56 | 
            +
                  let(:stack) { @stack }
         | 
| 63 57 |  | 
| 64 | 
            -
             | 
| 65 | 
            -
             | 
| 58 | 
            +
                  describe "collection" do
         | 
| 59 | 
            +
                    it "should include stack" do
         | 
| 60 | 
            +
                      orchestration.stacks.all.detect { |s| s.id == stack.id }.wont_be_nil
         | 
| 66 61 | 
             
                      orchestration.stacks.get(stack.id).wont_be_nil
         | 
| 67 62 | 
             
                    end
         | 
| 68 | 
            -
             | 
| 69 63 | 
             
                  end
         | 
| 70 64 |  | 
| 71 | 
            -
                  describe  | 
| 72 | 
            -
             | 
| 73 | 
            -
                    it 'should have a name' do
         | 
| 65 | 
            +
                  describe "instance methods" do
         | 
| 66 | 
            +
                    it "should have a name" do
         | 
| 74 67 | 
             
                      stack.name.must_equal build_args[:name]
         | 
| 75 68 | 
             
                    end
         | 
| 76 69 |  | 
| 77 | 
            -
                    it  | 
| 70 | 
            +
                    it "should be in :create_complete state" do
         | 
| 78 71 | 
             
                      stack.state.must_equal :create_complete
         | 
| 79 72 | 
             
                    end
         | 
| 80 73 |  | 
| 81 | 
            -
                    it  | 
| 74 | 
            +
                    it "should have a status" do
         | 
| 82 75 | 
             
                      stack.status.must_be_kind_of String
         | 
| 83 76 | 
             
                    end
         | 
| 84 77 |  | 
| 85 | 
            -
                    it  | 
| 78 | 
            +
                    it "should have a creation time" do
         | 
| 86 79 | 
             
                      stack.created.must_be_kind_of Time
         | 
| 87 80 | 
             
                    end
         | 
| 88 81 |  | 
| 89 | 
            -
                    it  | 
| 82 | 
            +
                    it "should have parameters used for creation" do
         | 
| 90 83 | 
             
                      stack.parameters.to_smash.must_equal build_args[:parameters].to_smash
         | 
| 91 84 | 
             
                    end
         | 
| 92 85 |  | 
| 93 | 
            -
                    it  | 
| 86 | 
            +
                    it "should include the templated used for creation" do
         | 
| 94 87 | 
             
                      stack.template.to_smash.must_equal build_args[:template].to_smash
         | 
| 95 88 | 
             
                    end
         | 
| 96 | 
            -
             | 
| 97 89 | 
             
                  end
         | 
| 98 | 
            -
             | 
| 99 90 | 
             
                end
         | 
| 100 91 |  | 
| 101 | 
            -
                describe  | 
| 102 | 
            -
                  it  | 
| 103 | 
            -
                    stack = orchestration.stacks.build(build_args.merge(:name =>  | 
| 92 | 
            +
                describe "instance lifecycle" do
         | 
| 93 | 
            +
                  it "should create new stack, reload details and destroy stack" do
         | 
| 94 | 
            +
                    stack = orchestration.stacks.build(build_args.merge(:name => "miasma-test-stack-2"))
         | 
| 104 95 | 
             
                    stack.save
         | 
| 105 96 | 
             
                    stack.id.wont_be_nil
         | 
| 106 97 | 
             
                    stack.state.must_equal :create_in_progress
         | 
| 107 98 | 
             
                    orchestration.stacks.reload.get(stack.id).wont_be_nil
         | 
| 108 | 
            -
                    until | 
| 99 | 
            +
                    until stack.state == :create_complete
         | 
| 109 100 | 
             
                      miasma_spec_sleep
         | 
| 110 101 | 
             
                      stack.reload
         | 
| 111 102 | 
             
                    end
         | 
| @@ -113,15 +104,13 @@ MIASMA_ORCHESTRATION_ABSTRACT = ->{ | |
| 113 104 | 
             
                    stack.destroy
         | 
| 114 105 | 
             
                    [:delete_in_progress, :delete_complete].must_include stack.state
         | 
| 115 106 | 
             
                    Timeout.timeout(500) do
         | 
| 116 | 
            -
                      until | 
| 107 | 
            +
                      until stack.state == :delete_complete
         | 
| 117 108 | 
             
                        miasma_spec_sleep
         | 
| 118 109 | 
             
                        stack.reload
         | 
| 119 110 | 
             
                      end
         | 
| 120 111 | 
             
                    end
         | 
| 121 112 | 
             
                    stack.state.must_equal :delete_complete
         | 
| 122 113 | 
             
                  end
         | 
| 123 | 
            -
             | 
| 124 114 | 
             
                end
         | 
| 125 | 
            -
             | 
| 126 115 | 
             
              end
         | 
| 127 116 | 
             
            }
         | 
| @@ -1,43 +1,39 @@ | |
| 1 | 
            -
            require  | 
| 1 | 
            +
            require "open-uri"
         | 
| 2 2 |  | 
| 3 | 
            -
            MIASMA_STORAGE_ABSTRACT = ->{
         | 
| 3 | 
            +
            MIASMA_STORAGE_ABSTRACT = -> {
         | 
| 4 4 |  | 
| 5 5 | 
             
              # Required `let`s:
         | 
| 6 6 | 
             
              # * storage: storage API
         | 
| 7 7 |  | 
| 8 8 | 
             
              describe Miasma::Models::Storage, :vcr do
         | 
| 9 | 
            -
             | 
| 10 | 
            -
                it 'should provide #buckets collection' do
         | 
| 9 | 
            +
                it "should provide #buckets collection" do
         | 
| 11 10 | 
             
                  storage.buckets.must_be_kind_of Miasma::Models::Storage::Buckets
         | 
| 12 11 | 
             
                end
         | 
| 13 12 |  | 
| 14 13 | 
             
                describe Miasma::Models::Storage::Buckets do
         | 
| 15 | 
            -
             | 
| 16 | 
            -
                  it 'should provide instance class used within collection' do
         | 
| 14 | 
            +
                  it "should provide instance class used within collection" do
         | 
| 17 15 | 
             
                    storage.buckets.model.must_equal Miasma::Models::Storage::Bucket
         | 
| 18 16 | 
             
                  end
         | 
| 19 17 |  | 
| 20 | 
            -
                  it  | 
| 18 | 
            +
                  it "should build new instance for collection" do
         | 
| 21 19 | 
             
                    storage.buckets.build.must_be_kind_of Miasma::Models::Storage::Bucket
         | 
| 22 20 | 
             
                  end
         | 
| 23 21 |  | 
| 24 | 
            -
                  it  | 
| 22 | 
            +
                  it "should provide #all buckets" do
         | 
| 25 23 | 
             
                    storage.buckets.all.must_be_kind_of Array
         | 
| 26 24 | 
             
                  end
         | 
| 27 | 
            -
             | 
| 28 25 | 
             
                end
         | 
| 29 26 |  | 
| 30 27 | 
             
                describe Miasma::Models::Storage::Bucket do
         | 
| 31 | 
            -
             | 
| 32 | 
            -
             | 
| 33 | 
            -
                    bucket = storage.buckets.build(:name => 'miasma-test-bucket-010')
         | 
| 28 | 
            +
                  it "should act like a bucket" do
         | 
| 29 | 
            +
                    bucket = storage.buckets.build(:name => "miasma-test-bucket-010")
         | 
| 34 30 | 
             
                    bucket.save
         | 
| 35 31 | 
             
                    bucket.reload
         | 
| 36 32 |  | 
| 37 33 | 
             
                    # should include the bucket
         | 
| 38 | 
            -
                    storage.buckets.reload.get( | 
| 34 | 
            +
                    storage.buckets.reload.get("miasma-test-bucket-010").wont_be_nil
         | 
| 39 35 | 
             
                    # should have a name
         | 
| 40 | 
            -
                    bucket.name.must_equal  | 
| 36 | 
            +
                    bucket.name.must_equal "miasma-test-bucket-010"
         | 
| 41 37 | 
             
                    # should have a #files collection
         | 
| 42 38 | 
             
                    bucket.files.must_be_kind_of Miasma::Models::Storage::Files
         | 
| 43 39 | 
             
                    #should provide #all files
         | 
| @@ -47,15 +43,15 @@ MIASMA_STORAGE_ABSTRACT = ->{ | |
| 47 43 | 
             
                    # should build new instance for collection
         | 
| 48 44 | 
             
                    bucket.files.build.must_be_kind_of Miasma::Models::Storage::File
         | 
| 49 45 |  | 
| 50 | 
            -
                    file_content =  | 
| 46 | 
            +
                    file_content = "blahblahblah"
         | 
| 51 47 | 
             
                    file = bucket.files.build
         | 
| 52 | 
            -
                    file.name =  | 
| 48 | 
            +
                    file.name = "miasma-test-file"
         | 
| 53 49 | 
             
                    file.body = file_content
         | 
| 54 50 | 
             
                    file.save
         | 
| 55 51 | 
             
                    file.reload
         | 
| 56 52 |  | 
| 57 53 | 
             
                    # should have a name
         | 
| 58 | 
            -
                    file.name.must_equal  | 
| 54 | 
            +
                    file.name.must_equal "miasma-test-file"
         | 
| 59 55 | 
             
                    # should have a size
         | 
| 60 56 | 
             
                    file.size.must_equal file_content.size
         | 
| 61 57 | 
             
                    # should have an updated timestamp
         | 
| @@ -67,9 +63,9 @@ MIASMA_STORAGE_ABSTRACT = ->{ | |
| 67 63 | 
             
                    file.body.readpartial(Miasma::Models::Storage::READ_BODY_CHUNK_SIZE).must_equal file_content
         | 
| 68 64 | 
             
                    file.destroy
         | 
| 69 65 |  | 
| 70 | 
            -
                    big_file_content =  | 
| 66 | 
            +
                    big_file_content = "*" * Miasma::Models::Storage::MAX_BODY_SIZE_FOR_STRINGIFY
         | 
| 71 67 | 
             
                    big_file = bucket.files.build
         | 
| 72 | 
            -
                    big_file.name =  | 
| 68 | 
            +
                    big_file.name = "miasma-test-file-big"
         | 
| 73 69 | 
             
                    big_file.body = big_file_content
         | 
| 74 70 | 
             
                    big_file.save
         | 
| 75 71 | 
             
                    big_file.reload
         | 
| @@ -82,14 +78,14 @@ MIASMA_STORAGE_ABSTRACT = ->{ | |
| 82 78 | 
             
                    content.must_equal big_file_content
         | 
| 83 79 | 
             
                    big_file.destroy
         | 
| 84 80 |  | 
| 85 | 
            -
                    require  | 
| 86 | 
            -
                    local_io_file = Tempfile.new( | 
| 87 | 
            -
                    big_io_content =  | 
| 81 | 
            +
                    require "tempfile"
         | 
| 82 | 
            +
                    local_io_file = Tempfile.new("miasma-storage-test")
         | 
| 83 | 
            +
                    big_io_content = "*" * (Miasma::Models::Storage::MAX_BODY_SIZE_FOR_STRINGIFY * 1.3)
         | 
| 88 84 | 
             
                    local_io_file.write big_io_content
         | 
| 89 85 | 
             
                    local_io_file.flush
         | 
| 90 86 | 
             
                    local_io_file.rewind
         | 
| 91 87 | 
             
                    remote_file = bucket.files.build
         | 
| 92 | 
            -
                    remote_file.name =  | 
| 88 | 
            +
                    remote_file.name = "miasma-test-io-object-010"
         | 
| 93 89 | 
             
                    remote_file.body = local_io_file
         | 
| 94 90 | 
             
                    remote_file.save
         | 
| 95 91 | 
             
                    remote_file.reload
         | 
| @@ -98,16 +94,14 @@ MIASMA_STORAGE_ABSTRACT = ->{ | |
| 98 94 | 
             
                    remote_file.size.must_equal local_io_file.size
         | 
| 99 95 | 
             
                    # should provide streaming body
         | 
| 100 96 | 
             
                    remote_file.body.must_respond_to :readpartial
         | 
| 101 | 
            -
                    content =  | 
| 102 | 
            -
                    while | 
| 97 | 
            +
                    content = ""
         | 
| 98 | 
            +
                    while chunk = remote_file.body.readpartial(1024)
         | 
| 103 99 | 
             
                      content << chunk
         | 
| 104 100 | 
             
                    end
         | 
| 105 101 | 
             
                    content.must_equal big_io_content
         | 
| 106 102 | 
             
                    remote_file.destroy
         | 
| 107 103 | 
             
                    bucket.destroy
         | 
| 108 104 | 
             
                  end
         | 
| 109 | 
            -
             | 
| 110 105 | 
             
                end
         | 
| 111 | 
            -
             | 
| 112 106 | 
             
              end
         | 
| 113 107 | 
             
            }
         | 
    
        data/lib/miasma/types.rb
    CHANGED
    
    | @@ -1,13 +1,11 @@ | |
| 1 | 
            -
            require  | 
| 1 | 
            +
            require "miasma"
         | 
| 2 2 |  | 
| 3 3 | 
             
            module Miasma
         | 
| 4 4 | 
             
              module Types
         | 
| 5 | 
            -
             | 
| 6 | 
            -
                autoload : | 
| 7 | 
            -
                autoload : | 
| 8 | 
            -
                autoload : | 
| 9 | 
            -
                autoload : | 
| 10 | 
            -
                autoload :Data, 'miasma/types/data'
         | 
| 11 | 
            -
             | 
| 5 | 
            +
                autoload :Api, "miasma/types/api"
         | 
| 6 | 
            +
                autoload :Collection, "miasma/types/collection"
         | 
| 7 | 
            +
                autoload :Model, "miasma/types/model"
         | 
| 8 | 
            +
                autoload :ThinModel, "miasma/types/thin_model"
         | 
| 9 | 
            +
                autoload :Data, "miasma/types/data"
         | 
| 12 10 | 
             
              end
         | 
| 13 11 | 
             
            end
         | 
    
        data/lib/miasma/types/api.rb
    CHANGED
    
    | @@ -1,4 +1,4 @@ | |
| 1 | 
            -
            require  | 
| 1 | 
            +
            require "miasma"
         | 
| 2 2 |  | 
| 3 3 | 
             
            module Miasma
         | 
| 4 4 | 
             
              module Types
         | 
| @@ -7,9 +7,9 @@ module Miasma | |
| 7 7 | 
             
                class Api
         | 
| 8 8 |  | 
| 9 9 | 
             
                  # HTTP request methods that are allowed retry
         | 
| 10 | 
            -
                  VALID_REQUEST_RETRY_METHODS=[:get, :head]
         | 
| 10 | 
            +
                  VALID_REQUEST_RETRY_METHODS = [:get, :head]
         | 
| 11 11 | 
             
                  # Maximum allowed HTTP request retries (for non-HTTP related errors)
         | 
| 12 | 
            -
                  MAX_REQUEST_RETRIES=5
         | 
| 12 | 
            +
                  MAX_REQUEST_RETRIES = 5
         | 
| 13 13 |  | 
| 14 14 | 
             
                  include Miasma::Utils::Lazy
         | 
| 15 15 | 
             
                  include Miasma::Utils::Memoization
         | 
| @@ -22,7 +22,7 @@ module Miasma | |
| 22 22 | 
             
                  # @return [self]
         | 
| 23 23 | 
             
                  def initialize(creds)
         | 
| 24 24 | 
             
                    custom_setup(creds)
         | 
| 25 | 
            -
                    if | 
| 25 | 
            +
                    if creds.is_a?(Hash)
         | 
| 26 26 | 
             
                      load_data(creds)
         | 
| 27 27 | 
             
                    else
         | 
| 28 28 | 
             
                      raise TypeError.new "Expecting `credentials` to be of type `Hash`. Received: `#{creds.class}`"
         | 
| @@ -51,7 +51,7 @@ module Miasma | |
| 51 51 |  | 
| 52 52 | 
             
                  # @return [Symbol] name of provider
         | 
| 53 53 | 
             
                  def provider
         | 
| 54 | 
            -
                    Utils.snake(self.class.to_s.split( | 
| 54 | 
            +
                    Utils.snake(self.class.to_s.split("::").last).to_sym
         | 
| 55 55 | 
             
                  end
         | 
| 56 56 |  | 
| 57 57 | 
             
                  # Connect to the remote API
         | 
| @@ -71,7 +71,7 @@ module Miasma | |
| 71 71 | 
             
                        Smash.new(
         | 
| 72 72 | 
             
                          :type => type,
         | 
| 73 73 | 
             
                          :provider => provider,
         | 
| 74 | 
            -
                          :credentials => attributes
         | 
| 74 | 
            +
                          :credentials => attributes,
         | 
| 75 75 | 
             
                        )
         | 
| 76 76 | 
             
                      )
         | 
| 77 77 | 
             
                    end
         | 
| @@ -79,12 +79,12 @@ module Miasma | |
| 79 79 |  | 
| 80 80 | 
             
                  # @return [HTTP]
         | 
| 81 81 | 
             
                  def connection
         | 
| 82 | 
            -
                    HTTP.headers( | 
| 82 | 
            +
                    HTTP.headers("User-Agent" => "miasma/v#{Miasma::VERSION}")
         | 
| 83 83 | 
             
                  end
         | 
| 84 84 |  | 
| 85 85 | 
             
                  # @return [String] url endpoint
         | 
| 86 86 | 
             
                  def endpoint
         | 
| 87 | 
            -
                     | 
| 87 | 
            +
                    "http://api.example.com"
         | 
| 88 88 | 
             
                  end
         | 
| 89 89 |  | 
| 90 90 | 
             
                  # Perform request to remote API
         | 
| @@ -98,9 +98,9 @@ module Miasma | |
| 98 98 | 
             
                  # @raises [Error::ApiError::RequestError]
         | 
| 99 99 | 
             
                  def request(args)
         | 
| 100 100 | 
             
                    args = args.to_smash
         | 
| 101 | 
            -
                    http_method = args.fetch(:method,  | 
| 102 | 
            -
                    unless | 
| 103 | 
            -
                      raise ArgumentError.new  | 
| 101 | 
            +
                    http_method = args.fetch(:method, "get").to_s.downcase.to_sym
         | 
| 102 | 
            +
                    unless HTTP::Request::METHODS.include?(http_method)
         | 
| 103 | 
            +
                      raise ArgumentError.new "Invalid request method provided!"
         | 
| 104 104 | 
             
                    end
         | 
| 105 105 | 
             
                    request_args = [].tap do |ary|
         | 
| 106 106 | 
             
                      _endpoint = args.delete(:endpoint) || endpoint
         | 
| @@ -114,7 +114,7 @@ module Miasma | |
| 114 114 | 
             
                      end
         | 
| 115 115 | 
             
                      ary.push(options) unless options.empty?
         | 
| 116 116 | 
             
                    end
         | 
| 117 | 
            -
                    if | 
| 117 | 
            +
                    if args[:headers]
         | 
| 118 118 | 
             
                      _connection = connection.headers(args[:headers])
         | 
| 119 119 | 
             
                      args.delete(:headers)
         | 
| 120 120 | 
             
                    else
         | 
| @@ -122,7 +122,7 @@ module Miasma | |
| 122 122 | 
             
                    end
         | 
| 123 123 | 
             
                    result = retryable_request(http_method) do
         | 
| 124 124 | 
             
                      res = make_request(_connection, http_method, request_args)
         | 
| 125 | 
            -
                      unless | 
| 125 | 
            +
                      unless [args.fetch(:expects, 200)].flatten.compact.map(&:to_i).include?(res.code)
         | 
| 126 126 | 
             
                        raise Error::ApiError::RequestError.new(res.reason, :response => res)
         | 
| 127 127 | 
             
                      end
         | 
| 128 128 | 
             
                      res
         | 
| @@ -145,7 +145,7 @@ module Miasma | |
| 145 145 | 
             
                      :ui => data[:retry_ui],
         | 
| 146 146 | 
             
                      :auto_run => false,
         | 
| 147 147 | 
             
                      &block
         | 
| 148 | 
            -
                    ).run!{|e| perform_request_retry(e) }
         | 
| 148 | 
            +
                    ).run! { |e| perform_request_retry(e) }
         | 
| 149 149 | 
             
                  end
         | 
| 150 150 |  | 
| 151 151 | 
             
                  # Determine if request type is allowed to be retried
         | 
| @@ -182,28 +182,27 @@ module Miasma | |
| 182 182 | 
             
                  # @param result [HTTP::Response]
         | 
| 183 183 | 
             
                  # @param extract_body [TrueClass, FalseClass] automatically extract body
         | 
| 184 184 | 
             
                  # @return [Smash]
         | 
| 185 | 
            -
                  def format_response(result, extract_body=true)
         | 
| 186 | 
            -
                    extracted_headers = Smash[result.headers.map{|k,v| [Utils.snake(k), v]}]
         | 
| 187 | 
            -
                    if | 
| 185 | 
            +
                  def format_response(result, extract_body = true)
         | 
| 186 | 
            +
                    extracted_headers = Smash[result.headers.map { |k, v| [Utils.snake(k), v] }]
         | 
| 187 | 
            +
                    if extract_body
         | 
| 188 188 | 
             
                      body_content = result.body.to_s
         | 
| 189 | 
            -
                      body_content.encode!( | 
| 190 | 
            -
             | 
| 191 | 
            -
             | 
| 192 | 
            -
             | 
| 193 | 
            -
                      )
         | 
| 194 | 
            -
                      if(extracted_headers[:content_type].to_s.include?('json'))
         | 
| 189 | 
            +
                      body_content.encode!("UTF-8", "binary",
         | 
| 190 | 
            +
                                           :invalid => :replace,
         | 
| 191 | 
            +
                                           :undef => :replace,
         | 
| 192 | 
            +
                                           :replace => "")
         | 
| 193 | 
            +
                      if extracted_headers[:content_type].to_s.include?("json")
         | 
| 195 194 | 
             
                        extracted_body = from_json(body_content) || body_content
         | 
| 196 | 
            -
                      elsif | 
| 195 | 
            +
                      elsif extracted_headers[:content_type].to_s.include?("xml")
         | 
| 197 196 | 
             
                        extracted_body = from_xml(body_content) || body_content
         | 
| 198 197 | 
             
                      else
         | 
| 199 198 | 
             
                        extracted_body = from_json(body_content) ||
         | 
| 200 | 
            -
             | 
| 201 | 
            -
             | 
| 199 | 
            +
                                         from_xml(body_content) ||
         | 
| 200 | 
            +
                                         body_content
         | 
| 202 201 | 
             
                      end
         | 
| 203 202 | 
             
                    end
         | 
| 204 | 
            -
                    unless | 
| 203 | 
            +
                    unless extracted_body
         | 
| 205 204 | 
             
                      # @note if body is over 100KB, do not extract
         | 
| 206 | 
            -
                      if | 
| 205 | 
            +
                      if extracted_headers[:content_length].to_i < 102400
         | 
| 207 206 | 
             
                        extracted_body = result.body.to_s
         | 
| 208 207 | 
             
                      else
         | 
| 209 208 | 
             
                        extracted_body = result.body
         | 
| @@ -212,7 +211,7 @@ module Miasma | |
| 212 211 | 
             
                    Smash.new(
         | 
| 213 212 | 
             
                      :response => result,
         | 
| 214 213 | 
             
                      :headers => extracted_headers,
         | 
| 215 | 
            -
                      :body => extracted_body
         | 
| 214 | 
            +
                      :body => extracted_body,
         | 
| 216 215 | 
             
                    )
         | 
| 217 216 | 
             
                  end
         | 
| 218 217 |  | 
| @@ -239,8 +238,6 @@ module Miasma | |
| 239 238 | 
             
                      nil
         | 
| 240 239 | 
             
                    end
         | 
| 241 240 | 
             
                  end
         | 
| 242 | 
            -
             | 
| 243 241 | 
             
                end
         | 
| 244 | 
            -
             | 
| 245 242 | 
             
              end
         | 
| 246 243 | 
             
            end
         | 
| @@ -1,11 +1,10 @@ | |
| 1 | 
            -
            require  | 
| 1 | 
            +
            require "miasma"
         | 
| 2 2 |  | 
| 3 3 | 
             
            module Miasma
         | 
| 4 4 | 
             
              module Types
         | 
| 5 5 |  | 
| 6 6 | 
             
                # Base collection
         | 
| 7 7 | 
             
                class Collection
         | 
| 8 | 
            -
             | 
| 9 8 | 
             
                  include Utils::Memoization
         | 
| 10 9 | 
             
                  include Utils::ApiMethoding
         | 
| 11 10 |  | 
| @@ -47,7 +46,7 @@ module Miasma | |
| 47 46 | 
             
                  # @return [Array<Model>]
         | 
| 48 47 | 
             
                  # @todo need to add helper to deep sort args, convert to string
         | 
| 49 48 | 
             
                  #   and hash to use as memoization key
         | 
| 50 | 
            -
                  def filter(args={})
         | 
| 49 | 
            +
                  def filter(args = {})
         | 
| 51 50 | 
             
                    key = "filter_#{args.to_smash.checksum}"
         | 
| 52 51 | 
             
                    memoize(key) do
         | 
| 53 52 | 
             
                      perform_filter(args)
         | 
| @@ -58,7 +57,7 @@ module Miasma | |
| 58 57 | 
             
                  #
         | 
| 59 58 | 
             
                  # @param args [Hash] creation options
         | 
| 60 59 | 
             
                  # @return [Model]
         | 
| 61 | 
            -
                  def build(args={})
         | 
| 60 | 
            +
                  def build(args = {})
         | 
| 62 61 | 
             
                    instance = self.model.new(self.api)
         | 
| 63 62 | 
             
                    args.each do |m_name, m_value|
         | 
| 64 63 | 
             
                      m_name = "#{m_name}="
         | 
| @@ -78,7 +77,7 @@ module Miasma | |
| 78 77 | 
             
                  # @return [self]
         | 
| 79 78 | 
             
                  def from_json(json)
         | 
| 80 79 | 
             
                    loaded = MultiJson.load(json)
         | 
| 81 | 
            -
                    unless | 
| 80 | 
            +
                    unless loaded.is_a?(Array)
         | 
| 82 81 | 
             
                      raise TypeError.new "Expecting type `Array` but received `#{loaded.class}`"
         | 
| 83 82 | 
             
                    end
         | 
| 84 83 | 
             
                    unmemoize(:collection)
         | 
| @@ -102,7 +101,7 @@ module Miasma | |
| 102 101 | 
             
                  # @param ident [String, Symbol] model identifier
         | 
| 103 102 | 
             
                  # @return [Model, NilClass]
         | 
| 104 103 | 
             
                  def perform_get(ident)
         | 
| 105 | 
            -
                    if | 
| 104 | 
            +
                    if m_name = api_method_for(:get)
         | 
| 106 105 | 
             
                      api.send(m_name, ident)
         | 
| 107 106 | 
             
                    else
         | 
| 108 107 | 
             
                      all.detect do |obj|
         | 
| @@ -114,7 +113,7 @@ module Miasma | |
| 114 113 |  | 
| 115 114 | 
             
                  # @return [Array<Model>]
         | 
| 116 115 | 
             
                  def perform_population
         | 
| 117 | 
            -
                    if | 
| 116 | 
            +
                    if m_name = api_method_for(:all)
         | 
| 118 117 | 
             
                      api.send(m_name)
         | 
| 119 118 | 
             
                    else
         | 
| 120 119 | 
             
                      raise NotImplementedError
         | 
| @@ -123,10 +122,10 @@ module Miasma | |
| 123 122 |  | 
| 124 123 | 
             
                  # @return [Array<Model>]
         | 
| 125 124 | 
             
                  def perform_filter(args)
         | 
| 126 | 
            -
                    if | 
| 125 | 
            +
                    if m_name = api_method_for(:filter)
         | 
| 127 126 | 
             
                      api.send(m_name, args)
         | 
| 128 127 | 
             
                    else
         | 
| 129 | 
            -
                      if | 
| 128 | 
            +
                      if args[:prefix]
         | 
| 130 129 | 
             
                        all.find_all do |item|
         | 
| 131 130 | 
             
                          item.name.start_with?(args[:prefix])
         | 
| 132 131 | 
             
                        end
         | 
| @@ -135,7 +134,6 @@ module Miasma | |
| 135 134 | 
             
                      end
         | 
| 136 135 | 
             
                    end
         | 
| 137 136 | 
             
                  end
         | 
| 138 | 
            -
             | 
| 139 137 | 
             
                end
         | 
| 140 138 | 
             
              end
         | 
| 141 139 | 
             
            end
         |