Class: LapisLazuli::Proxy

Inherits:
Object
  • Object
show all
Defined in:
lib/lapis_lazuli/proxy.rb

Overview

Proxy class to map to sc-proxy

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(ip, port, scproxy = true) ⇒ Proxy

Create a new LL Proxy What is the ip/port of the master?



22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/lapis_lazuli/proxy.rb', line 22

def initialize(ip, port, scproxy=true)
  # Save the information
  @ip = ip
  @is_scproxy = scproxy
  if scproxy
    @scproxy_port = port
  else
    @port = port
  end
  # We should have a master
  if !is_port_open?(ip, port)
    raise "Proxy not online"
  end
  if @is_scproxy
    # Create an API connection to the master
    @api = API.new()
  end
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(meth, *args, &block) ⇒ Object

Map any missing method to the API object

Example proxy.har_get proxy.proxy_close :port => 10002



120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
# File 'lib/lapis_lazuli/proxy.rb', line 120

def method_missing(meth, *args, &block)
  # Only for spritecloud proxies
  if !@is_scproxy
    raise "Incorrect method: #{meth}"
  end

  # We should have no arguments or a Hash
  if args.length > 1 or (args.length == 1 and not args[0].is_a? Hash)
    raise "Incorrect arguments: #{args}"
  end
  settings = args[0] || {}

  # A custom block or arguments?
  block = block_given? ? block : Proc.new do |req|
    if args.length == 1
      settings.each do |key,value|
        req.params[key.to_s] = value.to_s
      end
    end
  end

  # Pick the master proxy or the proxy for this session
  @api.set_conn("http://#{@ip}:#{(settings.has_key? :master) ? @scproxy_port : @port}/")

  # Call the API
  response = @api.get("/#{meth.to_s.gsub("_","/")}", nil, &block)
  # Only return the body if we could parse the JSOn
  if response.body.is_a? Hash
    return response.body
  else
    # Got a serious issue here, label as code 500
    return {
      "code" => 500,
      "status" => false,
      "message" => "Incorrect response from proxy",
      "result" => response
    }
  end
end

Instance Attribute Details

#apiObject (readonly)

Returns the value of attribute api.



17
18
19
# File 'lib/lapis_lazuli/proxy.rb', line 17

def api
  @api
end

#ipObject (readonly)

Returns the value of attribute ip.



17
18
19
# File 'lib/lapis_lazuli/proxy.rb', line 17

def ip
  @ip
end

#is_scproxyObject (readonly)

Returns the value of attribute is_scproxy.



17
18
19
# File 'lib/lapis_lazuli/proxy.rb', line 17

def is_scproxy
  @is_scproxy
end

#portObject (readonly)

Returns the value of attribute port.



17
18
19
# File 'lib/lapis_lazuli/proxy.rb', line 17

def port
  @port
end

#scproxy_portObject (readonly)

Returns the value of attribute scproxy_port.



17
18
19
# File 'lib/lapis_lazuli/proxy.rb', line 17

def scproxy_port
  @scproxy_port
end

Instance Method Details

#closeObject

Close the session with the proxy



75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/lapis_lazuli/proxy.rb', line 75

def close()
  # If we don't have one we don't do anything
  return if !@is_scproxy or !self.has_session?

  # Send the call to the master
  response = self.proxy_close :port => @port, :master => true

  # Did we close it?
  if response["status"] == true
    # Clear our session
    @port = nil
  else
    # Show an error
    raise response["message"]
  end
end

#createObject

Creates a new session with the proxy



47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/lapis_lazuli/proxy.rb', line 47

def create()
  # Do we already have a connection?
  if @is_scproxy and self.has_session?
    # Close it before starting a new one
    self.close()
  end
  # Create a new
  if @is_scproxy and @api
    # Let the master create a new proxy
    response = self.proxy_new :master => true
    # Did we get on?
    if response["status"] == true
      @port = response["result"]["port"]
    else
      # Show the error
      raise response["message"]
    end
  end

  if @port.nil?
    raise "Coult not create a new proxy"
  end

  return @port
end

#destroy(world) ⇒ Object

During the end of the test run all data should be added to the storage



162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
# File 'lib/lapis_lazuli/proxy.rb', line 162

def destroy(world)
  begin
    # Is it a spriteCloud proxy?
    if @is_scproxy
      # Request HAR data
      response = self.har_get
      if response["status"] == true
        # Add it to the storage
        world.storage.set("har", response["result"])
      end
    end
    self.close
  rescue StandardError => err
    world.log.debug("Failed to close the proxy: #{err}")
  end
end

#has_session?Boolean

Returns:

  • (Boolean)


41
42
43
# File 'lib/lapis_lazuli/proxy.rb', line 41

def has_session?()
  return !@port.nil? && is_port_open?(@ip, @port);
end

#is_port_open?(ip, port) ⇒ Boolean

Check if a TCP port is open on a host

Returns:

  • (Boolean)


94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/lapis_lazuli/proxy.rb', line 94

def is_port_open?(ip, port)
  begin
    # Timeout is important
    Timeout::timeout(1) do
      begin
        # Create the socket and close it
        s = TCPSocket.new(ip, port)
        s.close
        return true
      # If it fails the port is closed
      rescue Errno::ECONNREFUSED, Errno::EHOSTUNREACH
      end
    end
  rescue Timeout::Error
  end

  # Sorry port is closed
  return false
end