Fixed Find server URLs, AdaptDataService demo, support for new
[smartapi.git] / Common / Python / SmartAPI / agents / RegistrationAgent.py
1 #!/usr/bin/python
2
3 """ 
4 An example class for making a registration to the SMARTAPI registry using Python
5 """
6
7 import sys
8
9 from SmartAPI.agents.Agent import Agent
10 from SmartAPI.factory.RequestFactory import RequestFactory
11 from SmartAPI.common.ACTIVITIES import *
12 from SmartAPI.common.SmartAPICrypto import SmartAPICrypto
13 from SmartAPI.common.Tools import Tools
14 from SmartAPI.common.HttpClient import HttpClient
15 from SmartAPI.common.SERIALIZATION import SERIALIZATION
16 from SmartAPI.common.CONTENTTYPES import CONTENTTYPE
17 from SmartAPI.smartapiexceptions.InsufficientDataException import InsufficientDataException
18 from SmartAPI.common.URLs import *
19 from SmartAPI.common.RESOURCE import RESOURCE
20 from SmartAPI.common.PROPERTY import PROPERTY
21 from rdflib import URIRef
22 import traceback
23
24
25 class RegistrationAgent(Agent):
26     def __init__(self, registrantUri):
27         Agent.__init__(self)
28         self.generatedBy = registrantUri # smartapi identifier uri of the registrant
29         self.timestamp = None # timestamp of the sent registration request
30         self.entities = [] # list of entities to be registered
31         self.serialization = SERIALIZATION.TURTLE # rdf serialization of the registration message
32         self.debug = False
33         self.locked = False # switch to mark registration as locked so others cannot overwrite
34         self.serverAddress = FIND_URI  # uri of the SMARTAPI registration service
35     
36     def registrateAndLock(self):
37         self.locked = True
38         resp = self.registrate()
39         self.locked = False
40         return resp
41     
42     def registrate(self, entity = None, callback = None):
43         self.method = RESOURCE.WRITE
44         if entity is not None:
45             self.addEntity(entity)
46         return self.processRequest(callback)
47     
48     def deRegistrate(self, callback = None):
49         self.method = RESOURCE.DELETE
50         return self.processRequest(callback)
51         
52     def processRequest(self, callback):
53         messageBody = None
54         contentType = None
55         # Serialize data
56         try:
57             messageBody, contentType = self.generateEncryptedRegistrationMessage(self.getServerPublicKey())
58         except:
59             print "Exception while generating registration message."
60             traceback.print_exc()
61         
62         if self.debug:
63             import base64
64             print "Message created, encrypting with key", base64.b64encode(self.aesKey)
65         
66         try:
67             # send message
68             resp, respCxt = HttpClient().sendPost(self.getServerAddress(), messageBody, contentType)
69             if (self.debug):
70                 print "\nRegistration response (raw):"
71                 print resp, '\n'
72             # parse response
73             response = Tools.parseResponse(resp, respCxt)
74             if response.hasActivity():
75                 activity = response.firstActivity()
76                 # decrypt and return
77                 activity = activity.decrypt(self.aesKey)
78             
79                 if self.debug:
80                     print"\nRegistration activity:"
81                     activity.turtlePrint()
82             
83             # return in callback if provided
84             if callback is not None:
85                 callback.onResponse(response)
86             return response
87         
88         except:
89             print "Exception while sending an HTTP request to " + self.getServerAddress()
90             traceback.print_exc()
91         
92     def generateEncryptedRegistrationMessage(self, serverPublicKey):
93         request = None
94         try:
95             # check that there is something to register
96             if len(self.entities) < 1 and (self.method != RESOURCE.DELETE):
97                 raise InsufficientDataException("No SMARTAPI entities found in registration.")
98     
99             # build registration request
100             request = RequestFactory().createRegistrationRequest(self.generatedBy)
101             
102             # add registration entities
103             if self.method != RESOURCE.DELETE:
104                 activity = request.newActivity(REGISTER)
105                 activity.setEntities(self.entities)
106                 activity.setMethod(self.method)
107                 # set lock
108                 activity.add(URIRef(PROPERTY.LOCKED), self.locked)
109                 self.aesKey = activity.encryptWithPubKey(serverPublicKey)
110             
111         except:
112             traceback.print_exc()
113             return None, None
114
115         messageBody, contentType = Tools.serializeRequest(request, printDebug=self.debug)
116        
117         if self.debug:
118             print "\nRegistration request:"
119             print messageBody, "\n"
120         return messageBody, contentType
121     
122     def generateRegistrationMessage(self):
123         try:
124             # check that there is something to register
125             if len(self.entities) < 1 and (self.method != RESOURCE.DELETE):
126                 raise InsufficientDataException("No SMARTAPI entities found in registration.")
127     
128             # build registration request
129             request = RequestFactory().createRegistrationRequest(self.generatedBy)
130             request.setMethod(self.method)
131             
132             # add registration entities
133             if self.method != RESOURCE.DELETE:
134                 activity = request.newActivity(REGISTER)
135                 activity.setEntities(self.entities)
136                 # set lock
137                 activity.add(URIRef(PROPERTY.LOCKED), self.locked)
138             
139             if self.debug:
140                 print '\n *** registration request ****'
141                 request.turtlePrint()
142
143             return request
144             
145         except:
146             traceback.print_exc()
147             return None
148         
149     def setRegistrantUri(self, uri):
150         self.generatedBy = uri
151
152     def getRegistrantUri(self):
153         return self.generatedBy
154
155     def setRegistrationServiceUri(self, uri):
156         self.serverAddress = uri
157
158     def getRegistrationServiceUri(self):
159         return self.serverAddress
160
161     def addEntity(self, entity):
162         self.entities.append(entity)
163         
164     def entitiesSize(self):
165         return len(self.entities)
166     
167     def clearEntities(self):
168         self.entities = []
169         
170     def getSerialization(self):
171         return self.serialization
172
173     def setSerialization(self, serialization):
174         self.serialization = serialization
175     
176     def getServerPublicKey(self):
177         keyString = ""
178         key = None
179         try:
180             keyString = HttpClient().sendGet(FIND_KEY_URI)
181             key = SmartAPICrypto().extractPemFormatPublicKey(keyString, "RSA");
182         except:
183             print "Failed to get a key from the registration server."
184             print sys.exc_info()[1]
185         return key