~cgb-cs/appscale/appscale-main

« back to all changes in this revision

Viewing changes to AppController/lib/datastore_repo_on_appscale.rb

  • Committer: Chris Bunch
  • Date: 2012-02-26 03:20:57 UTC
  • Revision ID: cgb@cs.ucsb.edu-20120226032057-ad0cy0zgx4we4exc
adding in repo over app engine support, and tests for most of datastore repo on appscale and s3

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
# Programmer: Chris Bunch
2
2
 
3
3
 
4
 
require 'datastore'
5
 
 
6
 
 
7
 
# A class that abstracts away access to our Repository application (also known
8
 
# as the Repo), which is a Google App Engine app and thus an easy interface
9
 
# to any datastore that AppScale can run over.
10
 
class DatastoreRepoOnAppScale
 
4
require 'datastore_repo'
 
5
require 'helperfunctions'
 
6
require 'repo'
 
7
 
 
8
 
 
9
# An implementation of the Repository app that assumes it is running
 
10
# within AppScale. AppScale is assumed to start it up on its own.
 
11
class DatastoreRepoOnAppScale < DatastoreRepo
 
12
 
 
13
  
 
14
  # The host (IP, colon, port) that the Repo app is hosted at.
 
15
  attr_accessor :host
11
16
 
12
17
 
13
18
  # The name of this datastore, which we call AppDB since Neptune jobs
17
22
 
18
23
  
19
24
  # Creates a new connection to the Repo running on AppScale. Since AppScale
20
 
  # starts the Repo automatically, this initialization does not start it
21
 
  # or verify that it is running (although it perhaps should do the latter).
 
25
  # starts the Repo automatically, this initialization does not start it.
22
26
  def initialize(credentials)
23
 
    # TODO(cgb): how should we get/set @ip?
24
 
  end
25
 
 
26
 
 
27
 
  # Writes the contents of the remotely specified file to the local filesystem.
28
 
  def get_output_and_save_to_fs(appdb_path, local_path)
29
 
    data = get_output_and_return_contents(appdb_path)
30
 
    HelperFunctions.write_file(local_path, data)
31
 
  end
32
 
 
33
 
 
34
 
  # Returns the output of the given file as a string.
35
 
  def get_output_and_return_contents(appdb_path)
36
 
    Djinn.log_debug("attempting to get output for file [#{appdb_path}]")
37
 
    return do_http_get_for_get(appdb_path, :output)
38
 
  end
39
 
 
40
 
 
41
 
  # Writes the contents of the given file to a file hosted in the Repo.
42
 
  # If the given file is a directory, we also write all files / directories
43
 
  # found in that directory.
44
 
  def write_remote_file_from_local_file(appdb_path, local_path)
45
 
    if File.directory?(local_path)
46
 
      `ls #{local_path}`.split.each { |file|
47
 
        full_appdb_path = appdb_path + "/" + file
48
 
        full_local_path = local_path + "/" + file
49
 
        Djinn.log_debug("recursive dive - now saving remote " +
50
 
          "[#{full_appdb_path}], local [#{full_local_path}]")
51
 
        temp = write_remote_file_from_local_file(full_appdb_path, full_local_path)
52
 
        if !temp
53
 
          Djinn.log_debug("setting remote [#{full_appdb_path}] failed - reported [#{temp}]")
54
 
          return false
55
 
        end
56
 
      }
57
 
 
58
 
      return true
59
 
    else
60
 
      Djinn.log_debug("attempting to put local file #{local_path} into file #{appdb_path}")
61
 
      val = HelperFunctions.read_file(local_path, chomp=false)
62
 
      return do_http_post_for_set(appdb_path, :output, val)
63
 
    end
64
 
 
65
 
    return result
66
 
  end
67
 
 
68
 
 
69
 
  # Writes the contents of the given string to a file hosted in the Repo.
70
 
  def write_remote_file_from_string(appdb_path, string)
71
 
    Djinn.log_debug("attempting to put local file into location #{appdb_path}")
72
 
    return do_http_post_for_set(appdb_path, :output, string)
73
 
  end
74
 
 
75
 
 
76
 
  # Retrieves the access policy for the given file.
77
 
  def get_acl(appdb_path)
78
 
    Djinn.log_debug("attempting to get acl for file [#{appdb_path}]")
79
 
    return do_http_get_for_get(appdb_path, :acl)
80
 
  end
81
 
 
82
 
 
83
 
  # Sets the access policy for the given file hosted in the Repo.
84
 
  def set_acl(appdb_path, acl)
85
 
    Djinn.log_debug("attempting to set acl to [#{acl}] for file #{appdb_path}")
86
 
    return do_http_post_for_set(appdb_path, :acl, acl)
87
 
  end
88
 
 
89
 
 
90
 
  # Queries the Repo app to see if the given file exists.
91
 
  def does_file_exist?(appdb_path)
92
 
    result = HelperFunctions.shell("curl http://#{@ip}:8079/doesexist " +
93
 
      "-X POST -d 'SECRET=#{HelperFunctions.get_secret()}' " +
94
 
      "-d 'KEY=#{appdb_path}'")
95
 
    return result == "true"
96
 
  end
97
 
 
98
 
 
99
 
  # A convenience method that can be used to perform GET requests on the
100
 
  # Repo app, returning whatever it returns.
101
 
  def do_http_get_for_get(appdb_path, type)
102
 
    Djinn.log_debug("performing a get on key [#{key}], type [#{type}]")
103
 
    get_url = "http://#{@ip}:8079/get"
104
 
    params = {'SECRET' => @@secret, 'KEY' => key, 'TYPE' => type}
105
 
    data = Net::HTTP.post_form(URI.parse(get_url), params).body
106
 
    decoded_data = Base64.decode64(data)
107
 
    return data
108
 
  end
109
 
 
110
 
 
111
 
  # A convenience method that can be used to perform POST requests on the
112
 
  # Repo app, returning a boolean corresponding to if the operation succeeded.
113
 
  def do_http_post_for_set(appdb_path, type, val)
114
 
    encoded_val = Base64.encode64(val)
115
 
    set_url = "http://#{@ip}:8079/set"
116
 
    params = {'SECRET' => HelperFunctions.get_secret(), 'KEY' => appdb_path,
117
 
      'VALUE' => encoded_val, 'TYPE' => type}
118
 
    result = Net::HTTP.post_form(URI.parse(set_url), params).body
119
 
    Djinn.log_debug("set key=#{appdb_path} type=#{type} returned #{result}")
120
 
    if result == "success"
121
 
      return true
122
 
    else
123
 
      return false
124
 
    end
125
 
  end
 
27
    repo_ip = Repo.get_public_ip()
 
28
    repo_port = 8079  # TODO(cgb): replace with a class constant in Repo class
 
29
 
 
30
    @host = "#{repo_ip}:#{repo_port}"
 
31
    HelperFunctions.sleep_until_port_is_open(repo_ip, repo_port, 
 
32
      HelperFunctions::DONT_USE_SSL)
 
33
  end
 
34
 
 
35
 
126
36
end