Fixed newline characters throughout the code
[com/gs-lite.git] / bin / gshub.py
index 278c44f..e0cd082 100755 (executable)
-#!/usr/bin/python\r
-# ------------------------------------------------\r
-#   Copyright 2014 AT&T Intellectual Property\r
-#   Licensed under the Apache License, Version 2.0 (the "License");\r
-#   you may not use this file except in compliance with the License.\r
-#   You may obtain a copy of the License at\r
-#\r
-#     http://www.apache.org/licenses/LICENSE-2.0\r
-#\r
-#   Unless required by applicable law or agreed to in writing, software\r
-#   distributed under the License is distributed on an "AS IS" BASIS,\r
-#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
-#   See the License for the specific language governing permissions and\r
-#   limitations under the License.\r
-# -------------------------------------------\r
-\r
-# Implementation of GSHUB REST service\r
-# for announcement and discovery of gs instances, sources and sinks\r
-\r
-from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer\r
-import SocketServer\r
-import json\r
-import cgi\r
-import threading\r
-import getopt\r
-import sys\r
-import re\r
-import cgi\r
-import socket\r
-import json\r
-\r
-# lis of URLS for all the REST calls we will serve\r
-DISCOVER_INSTANCE_URL = '/v1/discover-instance'\r
-DISCOVER_INITINSTANCE_URL = '/v1/discover-initialized-instance'\r
-DISCOVER_SOURCE_URL =  '/v1/discover-source'\r
-DISCOVER_SINK_URL =  '/v1/discover-sink'\r
-DISCOVER_STARTPROCESSING_URL = '/v1/discover-start-processing'\r
-ANNOUNCE_INSTANCE_URL =  '/v1/announce-instance'\r
-ANNOUNCE_INITINSTANCE_URL =  '/v1/announce-initialized-instance'\r
-ANNOUNCE_SOURCE_URL =  '/v1/announce-source'\r
-ANNOUNCE_SINK_URL =  '/v1/announce-sink'\r
-ANNOUNCE_STARTPROCESSING_URL = '/v1/announce-start-processing'\r
-ANNOUNCE_STREAM_SUBSCRIPTION = '/v1/announce-stream-subscription'\r
-ANNOUNCE_FTA_INSTANCE = '/v1/announce-fta-instance'\r
-ANNOUNCE_METRICS = '/v1/log-metrics'\r
-\r
-# gs instance endpoints\r
-gs_instances = {}\r
-\r
-# initialized gs instances\r
-gs_init_instances = {}\r
-\r
-# instances for which processing started\r
-gs_startprocessing_instances = {}\r
-\r
-# source endpoints\r
-sources = {}\r
-\r
-# sink endpoints\r
-sinks = {}\r
-\r
-\r
-# exctract endpoint information from json data\r
-def extract_endpoint(data) :\r
-       name = ''\r
-       ip = ''\r
-       port = 0\r
-               \r
-       try :\r
-               doc = json.loads(str(data))     \r
-       except :\r
-               print ('Invalid json message ' + str(data))\r
-               return []\r
-       \r
-       for key in doc.keys() :\r
-               if key == 'name' :\r
-                       name = doc[key]\r
-               elif key == 'ip' :\r
-                       ip = doc[key]\r
-                       # validate ip address           \r
-                       try :\r
-                               socket.inet_pton(socket.AF_INET, ip)\r
-                       except :\r
-                               print ('Invalid IPV4 address ' + ip)\r
-                               ip = ''\r
-               elif key == 'port' :\r
-                       # validate port number\r
-                       try :\r
-                               port = int(doc[key])\r
-                       except :\r
-                               print ('Invalid port number ' + doc[key])\r
-                               port = 0\r
-       \r
-       if name == '' or ip == '' or port == 0 :\r
-               print ('Name, ip or port is missing from json message ' + str(doc))\r
-               return []\r
-       \r
-\r
-       return [name, ip, port]\r
-\r
-\r
-# extract instance name from json data\r
-def extract_instance_name(data) :\r
-       name = ''\r
-       \r
-       try :\r
-               doc = json.loads(str(data))     \r
-       except :\r
-               print ('Invalid json message ' + str(data))\r
-               return ''\r
-       \r
-       for key in doc.keys() :\r
-               if key == 'name' :\r
-                       name = doc[key]\r
-       \r
-       if name == '' :\r
-               print ('Name field is missing in json message ' + str(doc))\r
-       elif (name in gs_instances) == False:\r
-               print ('Attempt to announce the initialization or start of processing for unknown instance ' + name)\r
-               name = ''\r
-               \r
-       return name\r
-       \r
-# handler for HTTP requests. We will override do_POST and do_GET of BaseHTTPRequestHandler\r
-class Server(BaseHTTPRequestHandler) :\r
-\r
-       def do_POST(self):\r
-               if re.search(ANNOUNCE_INSTANCE_URL, self.path) != None:         \r
-                       print self.path\r
-                       print self.headers\r
-                       if self.headers.getheader('content-type') == 'application/json' :\r
-                               # Find content length\r
-                               content_len = 0\r
-                               for i in range(len(self.headers.keys())):\r
-                                       if self.headers.keys()[i] == 'content-length' :\r
-                                               content_len = int (self.headers.values()[i])\r
-                                               break\r
-                               if content_len != 0 :\r
-                                       # extract endpoint information\r
-                                       endpoint = extract_endpoint(self.rfile.read(content_len))\r
-                                       if endpoint == [] :\r
-                                               self.send_response(400)\r
-                                       else :\r
-                                               self.send_response(200)\r
-                                               gs_instances[endpoint[0]] = [endpoint[1], endpoint[2]]\r
-                               else :\r
-                                       self.send_response(400)\r
-\r
-                       else:\r
-                               self.send_response(400)\r
-                       self.end_headers()              \r
-                       \r
-               elif re.search(ANNOUNCE_INITINSTANCE_URL, self.path) != None:\r
-                       if self.headers.getheader('content-type') == 'application/json' :\r
-                               # Find content length\r
-                               content_len = 0\r
-                               for i in range(len(self.headers.keys())):\r
-                                       if self.headers.keys()[i] == 'content-length' :\r
-                                               content_len = int (self.headers.values()[i])\r
-                                               break\r
-                               if content_len != 0 :\r
-                                       # extract name of initialized gs instance                               \r
-                                       name = extract_instance_name(self.rfile.read(content_len))\r
-                                       if name == '' :\r
-                                               self.send_response(400)\r
-                                       else :\r
-                                               self.send_response(200)\r
-                                               gs_init_instances[name] = 1\r
-                               else :\r
-                                       self.send_response(400)\r
-\r
-                       else:\r
-                               self.send_response(400)\r
-                       self.end_headers()      \r
-                       \r
-               elif re.search(ANNOUNCE_SOURCE_URL, self.path) != None:\r
-                       if self.headers.getheader('content-type') == 'application/json' :\r
-                               # Find content length\r
-                               content_len = 0\r
-                               for i in range(len(self.headers.keys())):\r
-                                       if self.headers.keys()[i] == 'content-length' :\r
-                                               content_len = int (self.headers.values()[i])\r
-                                               break\r
-                               if content_len != 0 :\r
-                                       # extract endpoint information                          \r
-                                       endpoint = extract_endpoint(self.rfile.read(content_len))\r
-                                       if endpoint == [] :\r
-                                               self.send_response(400)\r
-                                       else :\r
-                                               self.send_response(200)\r
-                                               sources[endpoint[0]] = [endpoint[1], endpoint[2]]\r
-                               else :\r
-                                       self.send_response(400)\r
-\r
-                       else:\r
-                               self.send_response(400)\r
-                       self.end_headers()\r
-                       \r
-               elif re.search(ANNOUNCE_SINK_URL, self.path) != None:\r
-                       if self.headers.getheader('content-type') == 'application/json' :\r
-                               # Find content length\r
-                               content_len = 0\r
-                               for i in range(len(self.headers.keys())):\r
-                                       if self.headers.keys()[i] == 'content-length' :\r
-                                               content_len = int (self.headers.values()[i])\r
-                                               break\r
-                               if content_len != 0 :\r
-                                       # extract endpoint information                          \r
-                                       endpoint = extract_endpoint(self.rfile.read(content_len))\r
-                                       if endpoint == [] :\r
-                                               self.send_response(400)\r
-                                       else :\r
-                                               self.send_response(200)\r
-                                               sinks[endpoint[0]] = [endpoint[1], endpoint[2]]\r
-                               else :\r
-                                       self.send_response(400)\r
-\r
-                       else:\r
-                               self.send_response(400)\r
-                       self.end_headers()      \r
-                       \r
-               elif re.search(ANNOUNCE_STARTPROCESSING_URL, self.path) != None:\r
-                       if self.headers.getheader('content-type') == 'application/json' :\r
-                               # Find content length\r
-                               content_len = 0\r
-                               for i in range(len(self.headers.keys())):\r
-                                       if self.headers.keys()[i] == 'content-length' :\r
-                                               content_len = int (self.headers.values()[i])\r
-                                               break\r
-                               if content_len != 0 :\r
-                                       # extract name of initialized gs instance                               \r
-                                       name = extract_instance_name(self.rfile.read(content_len))\r
-                                       if name == '' :\r
-                                               self.send_response(400)\r
-                                       else :\r
-                                               self.send_response(200)\r
-                                               gs_startprocessing_instances[name] = 1\r
-                               else :\r
-                                       self.send_response(400)\r
-\r
-                       else:\r
-                               self.send_response(400)\r
-                       self.end_headers()\r
-                       \r
-               # we do not do any processing for ANNOUNCE_STREAM_SUBSCRIPTION, ANNOUNCE_FTA_INSTANCE and ANNOUNCE_METRICS in gshub simulator           \r
-               elif (re.search(ANNOUNCE_STREAM_SUBSCRIPTION, self.path) != None) or (re.search(ANNOUNCE_FTA_INSTANCE, self.path) != None) or (re.search(ANNOUNCE_METRICS, self.path) != None):\r
-                       if self.headers.getheader('content-type') == 'application/json' :\r
-                               # Find content length\r
-                               content_len = 0\r
-                               for i in range(len(self.headers.keys())):\r
-                                       if self.headers.keys()[i] == 'content-length' :\r
-                                               content_len = int (self.headers.values()[i])\r
-                                               break\r
-                               if content_len != 0 :                           \r
-                                       self.send_response(200)\r
-                               else :\r
-                                       self.send_response(400)\r
-\r
-                       else:\r
-                               self.send_response(400)\r
-                       self.end_headers()      \r
-                       \r
-               else:\r
-                       self.send_response(404)\r
-                       self.end_headers()\r
-               return\r
-               \r
-       def do_GET(self):\r
-               if re.search(DISCOVER_INSTANCE_URL + '/*', self.path) != None:\r
-                       instance = self.path.split('/')[-1]\r
-                       # check if this instance is registered\r
-                       if instance in gs_instances :\r
-                               self.send_response(200)\r
-                               self.send_header('Content-Type', 'application/json')\r
-                               self.end_headers()\r
-                               self.wfile.write(bytes("{\"ip\" : \"" + gs_instances[instance][0] + "\", \"port\": " + str(gs_instances[instance][1]) + "}"))\r
-                       else:\r
-                               self.send_response(400)\r
-                               self.end_headers()\r
-\r
-\r
-               elif re.search(DISCOVER_INITINSTANCE_URL + '/*', self.path) != None:\r
-                       instance = self.path.split('/')[-1]\r
-                       # check if this instance is initialized\r
-                       if instance in gs_init_instances :\r
-                               self.send_response(200)\r
-                               self.send_header('Content-Type', 'application/json')\r
-                               self.end_headers()\r
-                               self.wfile.write(bytes("{\"ip\" : \"" + gs_instances[instance][0] + "\", \"port\": " + str(gs_instances[instance][1]) + "}"))\r
-                       else:\r
-                               self.send_response(400)\r
-                               self.end_headers()\r
-\r
-               elif re.search(DISCOVER_SOURCE_URL + '/*', self.path) != None:\r
-                       source = self.path.split('/')[-1]\r
-                       # check if it is a registered source\r
-                       if source in sources :\r
-                               self.send_response(200)\r
-                               self.send_header('Content-Type', 'application/json')\r
-                               self.end_headers()\r
-                               self.wfile.write(bytes("{\"ip\" : \"" + sources[source][0] + "\", \"port\": " + str(sources[source][1]) + "}"))\r
-                       else:\r
-                               self.send_response(400)\r
-                               self.end_headers()\r
-                               \r
-               elif re.search(DISCOVER_SINK_URL + '/*', self.path) != None:\r
-                       sink = self.path.split('/')[-1]\r
-                       # check if it is a registered sink\r
-                       if sink in sinks :\r
-                               self.send_response(200)\r
-                               self.send_header('Content-Type', 'application/json')\r
-                               self.end_headers()\r
-                               self.wfile.write(bytes("{\"ip\" : \"" + sinks[sink][0] + "\", \"port\": " + str(sinks[sink][1]) + "}"))\r
-                       else:\r
-                               self.send_response(400)\r
-                               self.end_headers()\r
-                               \r
-               elif re.search(DISCOVER_STARTPROCESSING_URL + '/*', self.path) != None:\r
-                       instance = self.path.split('/')[-1]\r
-                       # check if this instance is initialized\r
-                       if instance in gs_startprocessing_instances :\r
-                               self.send_response(200)\r
-                               self.send_header('Content-Type', 'application/json')\r
-                               self.end_headers()\r
-                               self.wfile.write(bytes("{}"))\r
-                       else:\r
-                               self.send_response(400)\r
-                               self.end_headers()                              \r
-               else:\r
-                       self.send_response(404)\r
-                       self.end_headers()\r
-               return\r
-\r
-\r
-# print usage instructions\r
-def usage():\r
-       print ('./gshub.py [-p port]')\r
-       \r
-       \r
-\r
-def main():\r
-       # process command-line arguments\r
-       try:\r
-               opts, args = getopt.getopt(sys.argv[1:], "hp:v", ["help", "port="])\r
-       except getopt.GetoptError as err:\r
-               # print help information and exit:\r
-               print(str(err)) \r
-               usage()\r
-               sys.exit(2)\r
-\r
-       port = 0\r
-       for o, a in opts:\r
-               if o in ("-h", "--help"):\r
-                       usage()\r
-                       sys.exit(0)\r
-               elif o in ("-p", "--port"):\r
-                       port = int(a)\r
-               else:\r
-                       print ('Unknown command-line option ' + o)\r
-\r
-       # start HTTP server to serve REST calls\r
-       server_address = ('127.0.0.1', port)\r
-       httpd = HTTPServer(server_address, Server)\r
-\r
-       # record HTTP server address in gshub.log\r
-       f = open('gshub.log', 'w')\r
-       f.write(str(httpd.server_address[0]) + ':' + str(httpd.server_address[1]) + '\n')\r
-       f.close()\r
-               \r
-       print ('GSHUB Running on port ' + str(httpd.server_address[1]) + ' ...')\r
-\r
-       httpd.serve_forever()\r
-\r
-       \r
-if __name__ == "__main__":\r
-       main()\r
+#!/usr/bin/python
+# ------------------------------------------------
+#   Copyright 2014 AT&T Intellectual Property
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+# -------------------------------------------
+
+# Implementation of GSHUB REST service
+# for announcement and discovery of gs instances, sources and sinks
+
+from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer
+import SocketServer
+import json
+import cgi
+import threading
+import getopt
+import sys
+import re
+import cgi
+import socket
+import json
+
+# lis of URLS for all the REST calls we will serve
+DISCOVER_INSTANCE_URL = '/v1/discover-instance'
+DISCOVER_INITINSTANCE_URL = '/v1/discover-initialized-instance'
+DISCOVER_SOURCE_URL =  '/v1/discover-source'
+DISCOVER_SINK_URL =  '/v1/discover-sink'
+DISCOVER_STARTPROCESSING_URL = '/v1/discover-start-processing'
+ANNOUNCE_INSTANCE_URL =  '/v1/announce-instance'
+ANNOUNCE_INITINSTANCE_URL =  '/v1/announce-initialized-instance'
+ANNOUNCE_SOURCE_URL =  '/v1/announce-source'
+ANNOUNCE_SINK_URL =  '/v1/announce-sink'
+ANNOUNCE_STARTPROCESSING_URL = '/v1/announce-start-processing'
+ANNOUNCE_STREAM_SUBSCRIPTION = '/v1/announce-stream-subscription'
+ANNOUNCE_FTA_INSTANCE = '/v1/announce-fta-instance'
+ANNOUNCE_METRICS = '/v1/log-metrics'
+
+# gs instance endpoints
+gs_instances = {}
+
+# initialized gs instances
+gs_init_instances = {}
+
+# instances for which processing started
+gs_startprocessing_instances = {}
+
+# source endpoints
+sources = {}
+
+# sink endpoints
+sinks = {}
+
+
+# exctract endpoint information from json data
+def extract_endpoint(data) :
+       name = ''
+       ip = ''
+       port = 0
+               
+       try :
+               doc = json.loads(str(data))     
+       except :
+               print ('Invalid json message ' + str(data))
+               return []
+       
+       for key in doc.keys() :
+               if key == 'name' :
+                       name = doc[key]
+               elif key == 'ip' :
+                       ip = doc[key]
+                       # validate ip address           
+                       try :
+                               socket.inet_pton(socket.AF_INET, ip)
+                       except :
+                               print ('Invalid IPV4 address ' + ip)
+                               ip = ''
+               elif key == 'port' :
+                       # validate port number
+                       try :
+                               port = int(doc[key])
+                       except :
+                               print ('Invalid port number ' + doc[key])
+                               port = 0
+       
+       if name == '' or ip == '' or port == 0 :
+               print ('Name, ip or port is missing from json message ' + str(doc))
+               return []
+       
+
+       return [name, ip, port]
+
+
+# extract instance name from json data
+def extract_instance_name(data) :
+       name = ''
+       
+       try :
+               doc = json.loads(str(data))     
+       except :
+               print ('Invalid json message ' + str(data))
+               return ''
+       
+       for key in doc.keys() :
+               if key == 'name' :
+                       name = doc[key]
+       
+       if name == '' :
+               print ('Name field is missing in json message ' + str(doc))
+       elif (name in gs_instances) == False:
+               print ('Attempt to announce the initialization or start of processing for unknown instance ' + name)
+               name = ''
+               
+       return name
+       
+# handler for HTTP requests. We will override do_POST and do_GET of BaseHTTPRequestHandler
+class Server(BaseHTTPRequestHandler) :
+
+       def do_POST(self):
+               if re.search(ANNOUNCE_INSTANCE_URL, self.path) != None:         
+                       print self.path
+                       print self.headers
+                       if self.headers.getheader('content-type') == 'application/json' :
+                               # Find content length
+                               content_len = 0
+                               for i in range(len(self.headers.keys())):
+                                       if self.headers.keys()[i] == 'content-length' :
+                                               content_len = int (self.headers.values()[i])
+                                               break
+                               if content_len != 0 :
+                                       # extract endpoint information
+                                       endpoint = extract_endpoint(self.rfile.read(content_len))
+                                       if endpoint == [] :
+                                               self.send_response(400)
+                                       else :
+                                               self.send_response(200)
+                                               gs_instances[endpoint[0]] = [endpoint[1], endpoint[2]]
+                               else :
+                                       self.send_response(400)
+
+                       else:
+                               self.send_response(400)
+                       self.end_headers()              
+                       
+               elif re.search(ANNOUNCE_INITINSTANCE_URL, self.path) != None:
+                       if self.headers.getheader('content-type') == 'application/json' :
+                               # Find content length
+                               content_len = 0
+                               for i in range(len(self.headers.keys())):
+                                       if self.headers.keys()[i] == 'content-length' :
+                                               content_len = int (self.headers.values()[i])
+                                               break
+                               if content_len != 0 :
+                                       # extract name of initialized gs instance                               
+                                       name = extract_instance_name(self.rfile.read(content_len))
+                                       if name == '' :
+                                               self.send_response(400)
+                                       else :
+                                               self.send_response(200)
+                                               gs_init_instances[name] = 1
+                               else :
+                                       self.send_response(400)
+
+                       else:
+                               self.send_response(400)
+                       self.end_headers()      
+                       
+               elif re.search(ANNOUNCE_SOURCE_URL, self.path) != None:
+                       if self.headers.getheader('content-type') == 'application/json' :
+                               # Find content length
+                               content_len = 0
+                               for i in range(len(self.headers.keys())):
+                                       if self.headers.keys()[i] == 'content-length' :
+                                               content_len = int (self.headers.values()[i])
+                                               break
+                               if content_len != 0 :
+                                       # extract endpoint information                          
+                                       endpoint = extract_endpoint(self.rfile.read(content_len))
+                                       if endpoint == [] :
+                                               self.send_response(400)
+                                       else :
+                                               self.send_response(200)
+                                               sources[endpoint[0]] = [endpoint[1], endpoint[2]]
+                               else :
+                                       self.send_response(400)
+
+                       else:
+                               self.send_response(400)
+                       self.end_headers()
+                       
+               elif re.search(ANNOUNCE_SINK_URL, self.path) != None:
+                       if self.headers.getheader('content-type') == 'application/json' :
+                               # Find content length
+                               content_len = 0
+                               for i in range(len(self.headers.keys())):
+                                       if self.headers.keys()[i] == 'content-length' :
+                                               content_len = int (self.headers.values()[i])
+                                               break
+                               if content_len != 0 :
+                                       # extract endpoint information                          
+                                       endpoint = extract_endpoint(self.rfile.read(content_len))
+                                       if endpoint == [] :
+                                               self.send_response(400)
+                                       else :
+                                               self.send_response(200)
+                                               sinks[endpoint[0]] = [endpoint[1], endpoint[2]]
+                               else :
+                                       self.send_response(400)
+
+                       else:
+                               self.send_response(400)
+                       self.end_headers()      
+                       
+               elif re.search(ANNOUNCE_STARTPROCESSING_URL, self.path) != None:
+                       if self.headers.getheader('content-type') == 'application/json' :
+                               # Find content length
+                               content_len = 0
+                               for i in range(len(self.headers.keys())):
+                                       if self.headers.keys()[i] == 'content-length' :
+                                               content_len = int (self.headers.values()[i])
+                                               break
+                               if content_len != 0 :
+                                       # extract name of initialized gs instance                               
+                                       name = extract_instance_name(self.rfile.read(content_len))
+                                       if name == '' :
+                                               self.send_response(400)
+                                       else :
+                                               self.send_response(200)
+                                               gs_startprocessing_instances[name] = 1
+                               else :
+                                       self.send_response(400)
+
+                       else:
+                               self.send_response(400)
+                       self.end_headers()
+                       
+               # we do not do any processing for ANNOUNCE_STREAM_SUBSCRIPTION, ANNOUNCE_FTA_INSTANCE and ANNOUNCE_METRICS in gshub simulator           
+               elif (re.search(ANNOUNCE_STREAM_SUBSCRIPTION, self.path) != None) or (re.search(ANNOUNCE_FTA_INSTANCE, self.path) != None) or (re.search(ANNOUNCE_METRICS, self.path) != None):
+                       if self.headers.getheader('content-type') == 'application/json' :
+                               # Find content length
+                               content_len = 0
+                               for i in range(len(self.headers.keys())):
+                                       if self.headers.keys()[i] == 'content-length' :
+                                               content_len = int (self.headers.values()[i])
+                                               break
+                               if content_len != 0 :                           
+                                       self.send_response(200)
+                               else :
+                                       self.send_response(400)
+
+                       else:
+                               self.send_response(400)
+                       self.end_headers()      
+                       
+               else:
+                       self.send_response(404)
+                       self.end_headers()
+               return
+               
+       def do_GET(self):
+               if re.search(DISCOVER_INSTANCE_URL + '/*', self.path) != None:
+                       instance = self.path.split('/')[-1]
+                       # check if this instance is registered
+                       if instance in gs_instances :
+                               self.send_response(200)
+                               self.send_header('Content-Type', 'application/json')
+                               self.end_headers()
+                               self.wfile.write(bytes("{\"ip\" : \"" + gs_instances[instance][0] + "\", \"port\": " + str(gs_instances[instance][1]) + "}"))
+                       else:
+                               self.send_response(400)
+                               self.end_headers()
+
+
+               elif re.search(DISCOVER_INITINSTANCE_URL + '/*', self.path) != None:
+                       instance = self.path.split('/')[-1]
+                       # check if this instance is initialized
+                       if instance in gs_init_instances :
+                               self.send_response(200)
+                               self.send_header('Content-Type', 'application/json')
+                               self.end_headers()
+                               self.wfile.write(bytes("{\"ip\" : \"" + gs_instances[instance][0] + "\", \"port\": " + str(gs_instances[instance][1]) + "}"))
+                       else:
+                               self.send_response(400)
+                               self.end_headers()
+
+               elif re.search(DISCOVER_SOURCE_URL + '/*', self.path) != None:
+                       source = self.path.split('/')[-1]
+                       # check if it is a registered source
+                       if source in sources :
+                               self.send_response(200)
+                               self.send_header('Content-Type', 'application/json')
+                               self.end_headers()
+                               self.wfile.write(bytes("{\"ip\" : \"" + sources[source][0] + "\", \"port\": " + str(sources[source][1]) + "}"))
+                       else:
+                               self.send_response(400)
+                               self.end_headers()
+                               
+               elif re.search(DISCOVER_SINK_URL + '/*', self.path) != None:
+                       sink = self.path.split('/')[-1]
+                       # check if it is a registered sink
+                       if sink in sinks :
+                               self.send_response(200)
+                               self.send_header('Content-Type', 'application/json')
+                               self.end_headers()
+                               self.wfile.write(bytes("{\"ip\" : \"" + sinks[sink][0] + "\", \"port\": " + str(sinks[sink][1]) + "}"))
+                       else:
+                               self.send_response(400)
+                               self.end_headers()
+                               
+               elif re.search(DISCOVER_STARTPROCESSING_URL + '/*', self.path) != None:
+                       instance = self.path.split('/')[-1]
+                       # check if this instance is initialized
+                       if instance in gs_startprocessing_instances :
+                               self.send_response(200)
+                               self.send_header('Content-Type', 'application/json')
+                               self.end_headers()
+                               self.wfile.write(bytes("{}"))
+                       else:
+                               self.send_response(400)
+                               self.end_headers()                              
+               else:
+                       self.send_response(404)
+                       self.end_headers()
+               return
+
+
+# print usage instructions
+def usage():
+       print ('./gshub.py [-p port]')
+       
+       
+
+def main():
+       # process command-line arguments
+       try:
+               opts, args = getopt.getopt(sys.argv[1:], "hp:v", ["help", "port="])
+       except getopt.GetoptError as err:
+               # print help information and exit:
+               print(str(err)) 
+               usage()
+               sys.exit(2)
+
+       port = 0
+       for o, a in opts:
+               if o in ("-h", "--help"):
+                       usage()
+                       sys.exit(0)
+               elif o in ("-p", "--port"):
+                       port = int(a)
+               else:
+                       print ('Unknown command-line option ' + o)
+
+       # start HTTP server to serve REST calls
+       server_address = ('127.0.0.1', port)
+       httpd = HTTPServer(server_address, Server)
+
+       # record HTTP server address in gshub.log
+       f = open('gshub.log', 'w')
+       f.write(str(httpd.server_address[0]) + ':' + str(httpd.server_address[1]) + '\n')
+       f.close()
+               
+       print ('GSHUB Running on port ' + str(httpd.server_address[1]) + ' ...')
+
+       httpd.serve_forever()
+
+       
+if __name__ == "__main__":
+       main()