def requestInsert(face, repoCommandPrefix, fetchName, onInsertStarted, onFailed, startBlockId = None, endBlockId = None): """ Send a command interest for the repo to fetch the given fetchName and insert it in the repo. Since this calls expressInterest, your application must call face.processEvents. :param Face face: The Face used to call makeCommandInterest and expressInterest. :param Name repoCommandPrefix: The repo command prefix. :param Name fetchName: The name to fetch. If startBlockId and endBlockId are supplied, then the repo will request multiple segments by appending the range of block IDs (segment numbers). :param onInsertStarted: When the request insert command successfully returns, this calls onInsertStarted(). :type onInsertStarted: function object :param onFailed: If the command fails for any reason, this prints an error and calls onFailed(). :type onFailed: function object :param int startBlockId: (optional) The starting block ID (segment number) to fetch. :param int endBlockId: (optional) The end block ID (segment number) to fetch. """ # repo_command_parameter_pb2 was produced by protoc. parameter = repo_command_parameter_pb2.RepoCommandParameterMessage() # Add the Name. for i in range(fetchName.size()): parameter.repo_command_parameter.name.component.append( fetchName[i].getValue().toBytes()) # Add startBlockId and endBlockId if supplied. if startBlockId != None: parameter.repo_command_parameter.start_block_id = startBlockId if endBlockId != None: parameter.repo_command_parameter.end_block_id = endBlockId # Create the command interest. interest = Interest(Name(repoCommandPrefix).append("insert") .append(Name.Component(ProtobufTlv.encode(parameter)))) face.makeCommandInterest(interest) # Send the command interest and get the response or timeout. def onData(interest, data): # repo_command_response_pb2 was produced by protoc. response = repo_command_response_pb2.RepoCommandResponseMessage() try: ProtobufTlv.decode(response, data.content) except: dump("Cannot decode the repo command response") onFailed() if response.repo_command_response.status_code == 100: onInsertStarted() else: dump("Got repo command error code", response.repo_command_response.status_code) onFailed() def onTimeout(interest): dump("Insert repo command timeout") onFailed() face.expressInterest(interest, onData, onTimeout)
def stopRepoWatch(face, repoCommandPrefix, watchPrefix, onRepoWatchStopped, onFailed): """ Send a command interest for the repo to stop watching the given watchPrefix. Since this calls expressInterest, your application must call face.processEvents. :param Face face: The Face used to call makeCommandInterest and expressInterest. :param Name repoCommandPrefix: The repo command prefix. :param Name watchPrefix: The prefix that the repo will stop watching. :param onRepoWatchStopped: When the stop watch command successfully returns, this calls onRepoWatchStopped(). :type onRepoWatchStopped: function object :param onFailed: If the command fails for any reason, this prints an error and calls onFailed(). :type onFailed: function object """ # repo_command_parameter_pb2 was produced by protoc. parameter = repo_command_parameter_pb2.RepoCommandParameterMessage() for i in range(watchPrefix.size()): parameter.repo_command_parameter.name.component.append( watchPrefix[i].getValue().toBytes()) # Create the command interest. interest = Interest( Name(repoCommandPrefix).append("watch").append("stop").append( Name.Component(ProtobufTlv.encode(parameter)))) face.makeCommandInterest(interest) # Send the command interest and get the response or timeout. def onData(interest, data): # repo_command_response_pb2 was produced by protoc. response = repo_command_response_pb2.RepoCommandResponseMessage() try: ProtobufTlv.decode(response, data.content) except: dump("Cannot decode the repo command response") onFailed() if response.repo_command_response.status_code == 101: onRepoWatchStopped() else: dump("Got repo command error code", response.repo_command_response.status_code) onFailed() def onTimeout(interest): dump("Stop repo watch command timeout") onFailed() face.expressInterest(interest, onData, onTimeout)
def initiateContentStoreInsertion(self, repoCommandPrefix, data): fetchName = data.getName() parameter = repo_command_parameter_pb2.RepoCommandParameterMessage() # Add the Name. for i in range(fetchName.size()): parameter.repo_command_parameter.name.component.append( fetchName[i].getValue().toBytes()) # Create the command interest. interest = Interest(Name(repoCommandPrefix).append("insert") .append(Name.Component(ProtobufTlv.encode(parameter)))) self.face.makeCommandInterest(interest) self.face.expressInterest(interest, self.onRepoData, self.onRepoTimeout)
def requestInsert(face, repoCommandPrefix, fetchName, onInsertStarted, onFailed): # Construct a RepoCommandParameterMessage using the structure in # repo_command_parameter_pb2 which was produced by protoc. parameter = repo_command_parameter_pb2.RepoCommandParameterMessage() # Add the Name. msgName = parameter.Name() # 1. pattern name msgName.Clear() msgName.component.append(PATTERN_NAME[0].getValue().toBytes()) parameter.repo_command_parameter.name.component.append( ProtobufTlv.encode(msgName).toBytes()) # 2. fetch prefix msgName.Clear() for compo in fetchName: msgName.component.append(compo.getValue().toBytes()) parameter.repo_command_parameter.name.component.append( ProtobufTlv.encode(msgName).toBytes()) # Create the command interest. interest = Interest( Name(repoCommandPrefix).append("pattern").append( Name.Component(ProtobufTlv.encode(parameter)))) face.makeCommandInterest(interest) # Send the command interest and get the response or timeout. def onData(interest, data): # repo_command_response_pb2 was produced by protoc. response = repo_command_response_pb2.RepoCommandResponseMessage() try: ProtobufTlv.decode(response, data.content) except: dump("Cannot decode the repo command response") onFailed() if response.repo_command_response.status_code == 100: onInsertStarted() else: dump("Got repo command error code", response.repo_command_response.status_code) onFailed() def onTimeout(interest): dump("Pattern repo command timeout") onFailed() face.expressInterest(interest, onData, onTimeout)
def startRepoInsertion(self, data): # For now we only insert raw data into repo parameter = repo_command_parameter_pb2.RepoCommandParameterMessage() # Add the Name. for i in range(data.getName().size()): parameter.repo_command_parameter.name.component.append( data.getName().get(i).toEscapedString()) # Create the command interest. commandInterest = Interest( Name(repoCommandPrefix).append("insert").append( Name.Component(ProtobufTlv.encode(parameter)))) self._face.makeCommandInterest(commandInterest) # Send the command interest and get the response or timeout. def onRepoCommandResponse(interest, data): # repo_command_response_pb2 was produced by protoc. response = repo_command_response_pb2.RepoCommandResponseMessage() try: ProtobufTlv.decode(response, data.content) except: print("Cannot decode the repo command response") if response.repo_command_response.status_code == 100: if __debug__: print("Insertion started") else: print("Got repo command error code", response.repo_command_response.status_code) def onRepoCommandTimeout(interest): if __debug__: print("Insert repo command timeout") self._face.expressInterest(commandInterest, onRepoCommandResponse, onRepoCommandTimeout)
def publish(self, line): # Pull out and parse datetime for log entry # (note we shoudld use point time for timestamp) try: if not ": (point" in line: return point = parse.search("(point {})", line)[0].split(" ") except Exception as detail: print("publish: Parse error for", line, "-", detail) return try: tempTime = datetime.strptime( parse.search("[{}]", line)[0], "%Y-%m-%d %H:%M:%S.%f") except Exception as detail: print("publish: Date/time conversion error for", line, "-", detail) return sensorName = point[0] aggregationNamePrefix = self.pointNameToNDNName(sensorName) dataDict = self.pointToJSON(point) self._lastDataTimestamp = time.time() if aggregationNamePrefix is not None: #if __debug__: # print(dateTime, aggregationNamePrefix, dataDict["timestamp"], "payload:", dataDict["value"]) try: # TODO: since the leaf sensor publisher is not a separate node for now, we also publish aggregated data # of the same sensor over the past given time period in this code; # bms_node code has adaptation for leaf sensor publishers as well, ref: example-sensor1.conf # Here we make the assumption of fixed time window for *all* sensors # First publish aggregation dataTime = int(float(dataDict["timestamp"]) * 1000) if self._startTime == 0: self._startTime = dataTime if not (sensorName in self._dataQueue): # We don't have record of this sensor, so we create an identity for it, and print the cert string for now to get signed sensorIdentityName = Name(self._namespace).append( aggregationNamePrefix).getPrefix(-3) sensorCertificateName = self._keyChain.createIdentityAndCertificate( sensorIdentityName) if __debug__: print("Sensor identity name: " + sensorIdentityName.toUri()) certificateData = self._keyChain.getIdentityManager( )._identityStorage.getCertificate(sensorCertificateName, True) # We should only ask for cert to be signed upon the first run of a certain sensor if DO_CERT_SETUP: if (KeyLocator.getFromSignature( certificateData.getSignature()).getKeyName(). equals(sensorCertificateName.getPrefix(-1))): # Need to configure for remote gateway deployment; for now, remote uses its own branch with my public IP. print("certificate " + sensorCertificateName.toUri() + " asking for signature") response = urllib2.urlopen( "http://192.168.56.1:5000/bms-cert-hack?cert=" + b64encode( certificateData.wireEncode().toBuffer()) + "&cert_prefix=" + sensorIdentityName.toUri() + '&subject_name=' + sensorIdentityName.toUri()).read() signedCertData = Data() signedCertData.wireDecode(Blob( b64decode(response))) self._cache.add(signedCertData) cmdline = ['ndnsec-install-cert', '-'] p = subprocess.Popen(cmdline, stdin=subprocess.PIPE, stdout=subprocess.PIPE) cert, err = p.communicate(response) if p.returncode != 0: raise RuntimeError("ndnsec-install-cert error") else: self._cache.add(certificateData) else: self._cache.add(certificateData) self._dataQueue[sensorName] = DataQueueItem( [], self._startTime + self._defaultInterval, sensorIdentityName, sensorCertificateName) self._dataQueue[sensorName]._dataList.append( dataDict["value"]) elif dataTime > self._dataQueue[sensorName]._timeThreshold: # calculate the aggregation with what's already in the queue, publish data packet, and delete current queue # TODO: This should be mutex locked against self if len(self._dataQueue[sensorName]._dataList) > 0: avg = 0.0 for item in self._dataQueue[sensorName]._dataList: avg += float(item) avg = avg / len(self._dataQueue[sensorName]._dataList) data = Data( Name(self._namespace). append(aggregationNamePrefix).append("avg").append( str(self._dataQueue[sensorName]._timeThreshold) ).append( str(self._dataQueue[sensorName]._timeThreshold + self._defaultInterval))) data.setContent(str(avg)) data.getMetaInfo().setFreshnessPeriod( self.DEFAULT_DATA_LIFETIME) self._keyChain.sign( data, self._dataQueue[sensorName]._certificateName) self._cache.add(data) print("Aggregation produced " + data.getName().toUri()) self._dataQueue[sensorName]._dataList = [dataDict["value"]] self._dataQueue[ sensorName]._timeThreshold = self._dataQueue[ sensorName]._timeThreshold + self._defaultInterval else: self._dataQueue[sensorName]._dataList.append( dataDict["value"]) # Then publish raw data # Timestamp in data name uses the timestamp from data payload instDataPrefix = self.pointNameToNDNName(sensorName, False) dataTemp = self.createData( instDataPrefix, dataDict["timestamp"], json.dumps(dataDict), self._dataQueue[sensorName]._certificateName) if __debug__: print("Produced raw data name " + dataTemp.getName().toUri()) print("Produced raw data content " + dataTemp.getContent().toRawStr()) self._cache.add(dataTemp) # For now we only insert raw data into repo parameter = repo_command_parameter_pb2.RepoCommandParameterMessage( ) # Add the Name. for i in range(dataTemp.getName().size()): parameter.repo_command_parameter.name.component.append( dataTemp.getName().get(i).toEscapedString()) # Create the command interest. commandInterest = Interest( Name(repoCommandPrefix).append("insert").append( Name.Component(ProtobufTlv.encode(parameter)))) self._face.makeCommandInterest(commandInterest) # Send the command interest and get the response or timeout. def onRepoCommandResponse(interest, data): # repo_command_response_pb2 was produced by protoc. response = repo_command_response_pb2.RepoCommandResponseMessage( ) try: ProtobufTlv.decode(response, data.content) except: print("Cannot decode the repo command response") if response.repo_command_response.status_code == 100: if __debug__: print("Insertion started") else: print("Got repo command error code", response.repo_command_response.status_code) def onRepoCommandTimeout(interest): if __debug__: print("Insert repo command timeout") self._face.expressInterest(commandInterest, onRepoCommandResponse, onRepoCommandTimeout) except Exception as detail: print("publish: Error calling createData for", line, "-", detail)