-
Notifications
You must be signed in to change notification settings - Fork 1
/
MamocServer.py
155 lines (120 loc) · 6.16 KB
/
MamocServer.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
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
import os
from os import environ, path
import asyncio
from autobahn.asyncio.wamp import ApplicationSession, ApplicationRunner
from autobahn.wamp import ApplicationError, RegisterOptions
from JavaExecutor import JavaExecutor
from StatsCollector import StatsCollector
from Transformer import Transformer
def main():
import six
host = "127.0.0.1"
port = "8080"
url = environ.get("MAMOC_ROUTER", u"ws://"+host+":"+port+"/ws")
if six.PY2 and type(url) == six.binary_type:
url = url.decode('utf8')
realm = u"mamoc_realm"
runner = ApplicationRunner(url, realm)
try:
runner.run(MamocServer)
except OSError:
print("Failed to connect to Router!")
print("Are you sure there is a router component running at: " + host + " at port: " + port + "?")
class MamocServer(ApplicationSession):
def __init__(self, config=None):
ApplicationSession.__init__(self, config)
self.traceback_app = True
self.executor = JavaExecutor()
self.class_name = ""
self.resourcename = ""
self.params = ""
async def onJoin(self, details):
print("Mamoc Server attached on {}".format(details.session))
cpu, mem, battery = StatsCollector.fetchstats()
self.publish('uk.ac.standrews.cs.mamoc.stats', cpu, mem, battery)
print("published server stats")
# async def receive_file(n, details=None):
# if details.progress:
# for i in range(n):
# details.progress(i)
# await asyncio.sleep(1)
# else:
# await asyncio.sleep(1 * n)
# return n
#
# await self.register(receive_file, u'uk.ac.standrews.cs.mamoc.sendfile', RegisterOptions(details_arg='details'))
async def on_offloding_event(source, rpcname, code, resourcename, params):
print("Received from: {} app".format(source))
print("Received RCP name: {}".format(rpcname))
print("Received the source code: {}".format(code))
print("Received resource name: {}".format(resourcename))
print("Received params: {}".format(params))
if source == "Android":
self.class_name = rpcname
self.resourcename = resourcename
self.params = params
# Java file already cached in MAMoC Repository
if path.exists("java_classes/{}.java".format(self.class_name)):
result = self.executor.startExecuting(self.class_name, "{}.java".format(self.class_name), params)
else:
# if it is a class, it must start with package keyword
if code.strip().split(' ', 1)[0] == "package":
code, self.class_name = Transformer(code, resourcename, params).start()
else:
code, self.class_name = Transformer(code, resourcename, params).start(type="method")
print("class name returned from transformer: ", self.class_name)
with open("java_classes/{}.java".format(self.class_name), "w") as java_file:
print("{}".format(code), file=java_file)
# if resourcename is not None:
result = self.executor.startExecuting(self.class_name, "{}.java".format(self.class_name), resourcename, params)
# else:
# result = self.executor.startExecuting(self.class_name, "{}.java".format(self.class_name), params)
print(result)
if result: # if building and execution were successful, send back output and duration in seconds
output = result[0]
duration = result[1]
output = self.decode_bytes(output)
print("publishing result: {} that took {} seconds".format(output, duration))
self.publish('uk.ac.standrews.cs.mamoc.offloadingresult', output, duration)
# register the procedure for next time rpc request
try:
re = await self.register(execute_java, rpcname)
except ApplicationError as e:
print("could not register procedure: {0}".format(e))
else:
print("{} endpoints registered".format(re))
elif source == "iOS":
print("received from iOS app")
else:
print("unrecognized source!")
sub = await self.subscribe(on_offloding_event, "uk.ac.standrews.cs.mamoc.offloading")
print("Subscribed to uk.ac.standrews.cs.mamoc.offloading with {}".format(sub.id))
async def execute_java(resourcename, input):
print("execute_java {} {} {}".format(self.class_name, resourcename, input))
output, duration, errors = self.executor.execute_java(self.class_name, resourcename, input)
output = self.decode_bytes(output)
print("publishing result: {} that took {} seconds".format(output, duration))
self.publish('uk.ac.standrews.cs.mamoc.offloadingresult', output, duration)
return output, duration, errors
async def on_file_received_event(source, file_name, file_content):
print("Received file name: {}".format(file_name))
print("Received file content: {}".format(file_content))
if source == "Android":
resource_file = open("data/" + file_name, 'w+')
resource_file.write(file_content)
elif source == "iOS":
print("received from iOS app")
else:
print("unrecognized source!")
sub = await self.subscribe(on_file_received_event, "uk.ac.standrews.cs.mamoc.receive_file")
print("Subscribed to uk.ac.standrews.cs.mamoc.receive_file with {}".format(sub.id))
def decode_bytes(self, encoded):
if encoded == b'': # empty byte array
encoded = "nothing"
else:
encoded = encoded.decode("utf-8")
return encoded
def onDisconnect(self):
print("disconnected")
if __name__ == '__main__':
main()