oration 0.0.2 → 0.0.3

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.
Files changed (3) hide show
  1. data/templates/main.go +210 -0
  2. data/templates/main.py +160 -0
  3. metadata +6 -4
data/templates/main.go ADDED
@@ -0,0 +1,210 @@
1
+ // BEGIN CICERO-BOILERPLATE CODE
2
+ package CICERO_PKG_NAME
3
+
4
+ import (
5
+ "appengine"
6
+ "appengine/datastore"
7
+ "appengine/taskqueue"
8
+ "fmt"
9
+ "http"
10
+ "json"
11
+ "time"
12
+ )
13
+
14
+ type TaskInfo struct {
15
+ State string
16
+ StartTime datastore.Time
17
+ EndTime datastore.Time
18
+ }
19
+
20
+ type Text struct {
21
+ Content string
22
+ }
23
+
24
+ func init() {
25
+ http.HandleFunc("/task", taskRoute)
26
+ http.HandleFunc("/data", dataRoute)
27
+ http.HandleFunc("/compute", computeWorker)
28
+ http.HandleFunc("/", index)
29
+ }
30
+
31
+ func taskRoute(w http.ResponseWriter, r *http.Request) {
32
+ c := appengine.NewContext(r)
33
+
34
+ if r.Method == "GET" {
35
+ keyName := r.FormValue("task_id")
36
+ key := datastore.NewKey(c, "TaskInfo", keyName, 0, nil)
37
+ taskInfo := new(TaskInfo)
38
+ if err := datastore.Get(c, key, taskInfo); err == nil {
39
+ result := map[string]string{
40
+ "result": "success",
41
+ "state": taskInfo.State,
42
+ }
43
+ fmt.Fprintf(w, "%s", mapToJson(result))
44
+ return
45
+ } else {
46
+ result := map[string]string{
47
+ "result": "failure",
48
+ "state": "not found",
49
+ }
50
+ fmt.Fprintf(w, "%s", mapToJson(result))
51
+ return
52
+ }
53
+ } else if r.Method == "PUT" {
54
+ inputSource := r.FormValue("input1")
55
+ output := r.FormValue("output")
56
+ params := map[string][]string{
57
+ "input1": {inputSource},
58
+ "output": {output},
59
+ }
60
+
61
+ task := taskqueue.NewPOSTTask("/compute", params)
62
+ if newTask, err := taskqueue.Add(c, task, ""); err == nil {
63
+ result := map[string]string{
64
+ "result": "success",
65
+ "task_id": newTask.Name,
66
+ "output": output,
67
+ }
68
+ fmt.Fprintf(w, "%s", mapToJson(result))
69
+ return
70
+ } else {
71
+ result := map[string]string{
72
+ "result": "failure",
73
+ "reason": err.String(),
74
+ }
75
+ fmt.Fprintf(w, "%s", mapToJson(result))
76
+ return
77
+ }
78
+ } else {
79
+ // TODO - support deletion of tasks
80
+ http.Error(w, "method not supported", http.StatusInternalServerError)
81
+ return
82
+ }
83
+ }
84
+
85
+ func dataRoute(w http.ResponseWriter, r *http.Request) {
86
+ c := appengine.NewContext(r)
87
+
88
+ if r.Method == "GET" {
89
+ keyName := r.FormValue("location")
90
+
91
+ key := datastore.NewKey(c, "Text", keyName, 0, nil)
92
+ output := new(Text)
93
+ if err := datastore.Get(c, key, output); err != nil {
94
+ result := map[string]string{
95
+ "result": "failure",
96
+ "reason": err.String(),
97
+ }
98
+ fmt.Fprintf(w, "%s", mapToJson(result))
99
+ return
100
+ }
101
+
102
+ if output.Content == "" {
103
+ result := map[string]string{
104
+ "result": "failure",
105
+ "reason": "key did not exist",
106
+ }
107
+
108
+ fmt.Fprintf(w, "%s", mapToJson(result))
109
+ return
110
+ } else {
111
+ result := map[string]string{
112
+ "result": "success",
113
+ "output": output.Content,
114
+ }
115
+
116
+ fmt.Fprintf(w, "%s", mapToJson(result))
117
+ return
118
+ }
119
+ } else if r.Method == "PUT" {
120
+ keyName := r.FormValue("location")
121
+ key := datastore.NewKey(c, "Text", keyName, 0, nil)
122
+ text := Text{
123
+ Content: r.FormValue("text"),
124
+ }
125
+ key, err := datastore.Put(c, key, &text)
126
+ if err == nil {
127
+ result := map[string]string{
128
+ "result": "success",
129
+ }
130
+ fmt.Fprintf(w, "%s", mapToJson(result))
131
+ return
132
+ } else {
133
+ result := map[string]string{
134
+ "result": "failure",
135
+ "reason": err.String(),
136
+ }
137
+ fmt.Fprintf(w, "%s", mapToJson(result))
138
+ return
139
+ }
140
+ } else if r.Method == "DELETE" {
141
+ keyName := r.FormValue("location")
142
+
143
+ key := datastore.NewKey(c, "Text", keyName, 0, nil)
144
+ err := datastore.Delete(c, key)
145
+
146
+ if err == nil {
147
+ result := map[string]string{
148
+ "result": "success",
149
+ }
150
+ fmt.Fprintf(w, "%s", mapToJson(result))
151
+ return
152
+ } else {
153
+ result := map[string]string{
154
+ "result": "failure",
155
+ "reason": fmt.Sprintf("%s", err),
156
+ }
157
+ fmt.Fprintf(w, "%s", mapToJson(result))
158
+ return
159
+ }
160
+ } else {
161
+ http.Error(w, "method not supported", http.StatusInternalServerError)
162
+ return
163
+ }
164
+ }
165
+
166
+ func computeWorker(w http.ResponseWriter, r *http.Request) {
167
+ c := appengine.NewContext(r)
168
+
169
+ outputDest := r.FormValue("output")
170
+
171
+ keyName := outputDest // TODO - this should use the task id, not the output location
172
+ key := datastore.NewKey(c, "TaskInfo", keyName, 0, nil)
173
+
174
+ taskInfo := TaskInfo{
175
+ State: "started",
176
+ StartTime: datastore.SecondsToTime(time.Seconds()),
177
+ }
178
+
179
+ datastore.Put(c, key, &taskInfo)
180
+
181
+ outputTextKeyName := outputDest
182
+ outputTextKey := datastore.NewKey(c, "Text", outputTextKeyName, 0, nil)
183
+ outputText := Text{
184
+ Content: CICERO_FUNCTION_NAME(),
185
+ }
186
+ datastore.Put(c, outputTextKey, &outputText)
187
+
188
+ datastore.Get(c, key, &taskInfo)
189
+ taskInfo.State = "finished"
190
+ taskInfo.EndTime = datastore.SecondsToTime(time.Seconds())
191
+ datastore.Put(c, key, &taskInfo)
192
+ }
193
+
194
+ func index(w http.ResponseWriter, r *http.Request) {
195
+ fmt.Fprint(w, "Hello, world!")
196
+ }
197
+
198
+ func mapToJson(mapToConvert map[string]string) []byte {
199
+ jsonResult, err := json.Marshal(mapToConvert)
200
+ if err != nil {
201
+ fmt.Printf("json marshalling saw error: %s\n", err)
202
+ }
203
+
204
+ return jsonResult
205
+ }
206
+
207
+ // END CICERO-BOILERPLATE CODE
208
+ // BEGIN USER-PROVIDED FUNCTION
209
+ CICERO_FUNCTION_CONTENTS
210
+ // END USER-PROVIDED FUNCTION
data/templates/main.py ADDED
@@ -0,0 +1,160 @@
1
+ ##### BEGIN CICERO-BOILERPLATE CODE #####
2
+ try:
3
+ import simplejson as json
4
+ except ImportError:
5
+ import json
6
+
7
+ import datetime
8
+ import logging
9
+ import os
10
+ import StringIO
11
+ import wsgiref.handlers
12
+
13
+ from google.appengine.api import taskqueue
14
+
15
+ from google.appengine.ext import db
16
+ from google.appengine.ext import webapp
17
+ from google.appengine.ext.webapp import template
18
+ from google.appengine.ext.webapp import util
19
+
20
+ import CICERO_PACKAGE_NAME
21
+
22
+
23
+ class TaskInfo(db.Model):
24
+ state = db.StringProperty()
25
+ start_time = db.DateTimeProperty()
26
+ end_time = db.DateTimeProperty()
27
+
28
+
29
+ class Text(db.Model):
30
+ content = db.TextProperty()
31
+
32
+
33
+ class TaskRoute(webapp.RequestHandler):
34
+ def get(self):
35
+ key_name = self.request.get('task_id')
36
+ task_info = TaskInfo.get_by_key_name(key_name)
37
+ result = {} # TODO - see if we can remove that
38
+ try:
39
+ result = {'result':'success', 'state':task_info.state}
40
+ except AttributeError:
41
+ result = {'result':'failure', 'state':'not found'}
42
+
43
+ self.response.out.write(json.dumps(result))
44
+
45
+ def put(self):
46
+ allowed_routes = ['CICERO_FUNCTION_NAME']
47
+ function = self.request.get('f')
48
+ input_source = self.request.get('input1')
49
+ json_data = {'f':function, 'input1':input_source}
50
+
51
+ output = ''
52
+ if self.request.get('output') == '':
53
+ key_length = 16 # for now, randomly generates keys 16 chars long
54
+ json_data['output'] = os.urandom(key_length) # TODO - does this work in app engine?
55
+ else:
56
+ json_data['output'] = str(self.request.get('output'))
57
+ output = str(json_data['output'])
58
+
59
+ if function in allowed_routes:
60
+ url = '/' + function
61
+ logging.debug('starting a request for url ' + url)
62
+ new_task = taskqueue.add(url=url, params={'data': json.dumps(json_data)})
63
+ # TODO - adding the task does not imply success - when does it not?
64
+ result = {'result':'success', 'task_id':new_task.name, 'output':output}
65
+ logging.debug('result of job with input data' + str(json_data) + ' was ' + str(result))
66
+ self.response.out.write(json.dumps(result))
67
+ else:
68
+ reason = 'Cannot add a task for function type ' + str(function)
69
+ result ={'result':'failure', 'reason':reason}
70
+ self.response.out.write(json.dumps(result))
71
+
72
+ def delete(self):
73
+ task_id = self.request.get('task_id')
74
+ task = taskqueue.Task(name=task_id)
75
+ q = taskqueue.Queue()
76
+ cancel_info = q.delete_tasks(task)
77
+ logging.debug('cancel_info is ' + str(cancel_info))
78
+ result = {'result':'unknown', 'reason':str(cancel_info)}
79
+ self.response.out.write(result)
80
+
81
+
82
+ class DataRoute(webapp.RequestHandler):
83
+ def get(self):
84
+ key_name = self.request.get('location')
85
+ output = Text.get_by_key_name(key_name)
86
+ result = {} # TODO - see if we can remove that
87
+ try:
88
+ result = {'result':'success', 'output':output.content}
89
+ except AttributeError:
90
+ result = {'result':'failure', 'reason':'key did not exist'}
91
+
92
+ self.response.out.write(json.dumps(result))
93
+
94
+ def put(self):
95
+ key_name = self.request.get('location')
96
+ output = Text(key_name = key_name)
97
+ output.content = self.request.get('text')
98
+ output.put()
99
+
100
+ result = {'result':'success'}
101
+ self.response.out.write(json.dumps(result))
102
+
103
+ def delete(self):
104
+ key_name = self.request.get('location')
105
+
106
+ text = Text(key_name = key_name)
107
+ result = {}
108
+ try:
109
+ text.delete()
110
+ result = {'result':'success'}
111
+ except Exception:
112
+ result = {'result':'failure', 'reason':'exception was thrown'} # TODO get the name of the exception here
113
+
114
+ self.response.out.write(result)
115
+
116
+
117
+ class ComputeWorker(webapp.RequestHandler):
118
+ def post(self):
119
+ raw_data = self.request.get('data')
120
+ json_data = json.loads(raw_data)
121
+ input_source = str(json_data['input1'])
122
+ output_dest = str(json_data['output'])
123
+
124
+ # TODO - this should use the task id, not the output location
125
+ task_info = TaskInfo(key_name = output_dest)
126
+ task_info.state = "started"
127
+ task_info.start_time = datetime.datetime.now()
128
+ task_info.put()
129
+
130
+ output_text = Text(key_name = output_dest)
131
+ output_text.content = str(CICERO_PACKAGE_AND_FUNCTION_NAME())
132
+ output_text.put()
133
+
134
+ task_info = TaskInfo.get_by_key_name(output_dest)
135
+ task_info.state = "finished"
136
+ task_info.end_time = datetime.datetime.now()
137
+ task_info.put()
138
+
139
+
140
+ class IndexPage(webapp.RequestHandler):
141
+ def get(self):
142
+ # TODO(cgb): write something nicer about oration here!
143
+ self.response.out.write("hello!")
144
+
145
+ def main():
146
+ logging.getLogger().setLevel(logging.DEBUG)
147
+ application = webapp.WSGIApplication([('/task', TaskRoute),
148
+ ('/data', DataRoute),
149
+ ('/CICERO_FUNCTION_NAME', ComputeWorker),
150
+ ('/', IndexPage),
151
+ ],
152
+ debug=True)
153
+ util.run_wsgi_app(application)
154
+
155
+
156
+ if __name__ == '__main__':
157
+ main()
158
+
159
+
160
+ ##### END CICERO-BOILERPLATE CODE #####
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: oration
3
3
  version: !ruby/object:Gem::Version
4
- hash: 27
4
+ hash: 25
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 2
10
- version: 0.0.2
9
+ - 3
10
+ version: 0.0.3
11
11
  platform: ruby
12
12
  authors:
13
13
  - Chris Bunch
@@ -15,7 +15,7 @@ autorequire: oration
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2012-01-22 00:00:00 -08:00
18
+ date: 2012-01-25 00:00:00 -08:00
19
19
  default_executable: oration
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -80,6 +80,8 @@ files:
80
80
  - test/test_generator.rb
81
81
  - test/test_oration.rb
82
82
  - test/ts_all.rb
83
+ - templates/main.go
84
+ - templates/main.py
83
85
  - LICENSE
84
86
  has_rdoc: true
85
87
  homepage: http://appscale.cs.ucsb.edu