def checkReservation(self, resource, start_time, end_time): self._checkArgs(resource, start_time, end_time) # check start time is before end time if start_time is not None and end_time is not None and start_time > end_time: raise error.PayloadError( 'Invalid request: Reverse duration (end time before start time)' ) if start_time is not None: # check that start time is not in the past now = datetime.datetime.utcnow() if start_time < now: delta = now - start_time stamp = str(start_time).rsplit('.')[0] variables = [('startTime', start_time.isoformat())] raise error.PayloadError( 'Invalid request: Start time in the past (Startime: %s, Delta: %s)' % (stamp, str(delta)), variables=variables) # check the start time makes sense if start_time > datetime.datetime(2025, 1, 1): raise error.PayloadError( 'Invalid request: Start time after year 2025') for (c_resource, c_start_time, c_end_time) in self.reservations: if resource == c_resource: if self._resourceOverlap(c_start_time, c_end_time, start_time, end_time): raise error.STPUnavailableError( 'Resource %s not available in specified time span' % resource)
def parseLabel(label_part): if not '=' in label_part: raise error.PayloadError('No = in urn label part (%s)' % label_part) label_short_type, label_value = label_part.split('=') try: label_type = LABEL_MAP[label_short_type] except KeyError: raise error.PayloadError('Label type %s not recognized') return nsa.Label(label_type, label_value)
def _checkTiming(self, res_start, res_end): # check that ports are available in the specified schedule if res_start in [ None, '' ] or res_end in [ None, '' ]: raise error.MissingParameterError('Reservation must specify start and end time (was either None or '')') # sanity checks if res_start > res_end: raise error.PayloadError('Refusing to make reservation with reverse duration') if res_start < datetime.datetime.now(tzutc()): raise error.PayloadError('Refusing to make reservation with start time in the past') if res_start > datetime.datetime(2025, 1, 1): raise error.PayloadError('Refusing to make reservation with start time after 2025')
def createValue(value): try: if '-' in value: v1, v2 = value.split('-', 1) i1, i2 = int(v1), int(v2) if i1 > i2: raise error.PayloadError( 'Label value %s is in descending order, which is not allowed.' % value) else: i1 = int(value) i2 = i1 return i1, i2 except ValueError: raise error.PayloadError( 'Label %s is not an integer or an integer range.' % value)
def parseXMLTimestamp(xsd_timestamp): dt = iso8601.parse(xsd_timestamp) if dt.utcoffset() is None: # this needs to changed to valueerror... raise error.PayloadError('Timestamp has no time zone information') # convert to utc and remove tz info (internal use) utc_dt = dt.astimezone(UTC()).replace(tzinfo=None) return utc_dt
def createSTP(stp_id): if not stp_id.startswith(URN_NETWORK): raise error.PayloadError('STP Id (%s) did not start with %s' % (stp_id, URN_NETWORK)) tsi = stp_id.replace(URN_NETWORK, '') if '?' in tsi: loc, lbp = tsi.split('?') label = parseLabel(lbp) else: loc = tsi label = None if not ':' in loc: raise error.PayloadError('No : in stp urn (%s)' % loc) network, port = loc.rsplit(':', 1) return nsa.STP(network, port, label)
def createSTP(stp_id): if not stp_id.startswith(URN_NETWORK): raise error.PayloadError('STP Id (%s) did not start with %s' % (stp_id, URN_NETWORK)) tsi = stp_id.replace(URN_NETWORK, '') if '?' in tsi: loc, lbp = tsi.split('?') label = parseLabel(lbp) else: loc = tsi label = None if not ':' in loc: raise error.PayloadError('Invalid STP: No ":" in stp urn (%s)' % loc) # FIXME This may need to be updated for new stp structure (Uppsala) network, port = loc.rsplit(':', 1) return nsa.STP(network, port, label)
def parseXMLTimestamp(xsd_timestamp): xtp = parser.parser() dt = xtp.parse(xsd_timestamp) if dt.utcoffset() is None: # this needs to changed to valueerror... from opennsa import error raise error.PayloadError('Timestamp has no time zone information') # convert to utc and remove tz info (internal use) utc_dt = dt.astimezone(tzutc()).replace(tzinfo=None) return utc_dt
def reserve(self, soap_data): t_start = time.time() header, reservation = helper.parseRequest(soap_data) # do some checking here # print header.protocolVersion # print header.correlationId # print header.requesterNSA # print header.providerNSA # print header.replyTo criteria = reservation.criteria #version = criteria.version # not used at the moment service_type = criteria.serviceType # right now we just ignore this, either we know the service type or not p2ps = criteria.serviceDefinition # if len(service_defs) == 0: # err = failure.Failure ( error.PayloadError('No service definition element in message') ) # return self._createSOAPFault(err, header.provider_nsa, service_type=service_type) # if len(service_defs) != 1: # err = failure.Failure ( error.PayloadError('Only one service definition allowed') ) # return self._createSOAPFault(err, header.provider_nsa, service_type=service_type) if type(p2ps) is not p2pservices.P2PServiceBaseType: err = failure.Failure( error.PayloadError( 'Only supports Point2PointService service for now.')) return self._createSOAPFault(err, header.provider_nsa, service_type=service_type) if p2ps.directionality in (None, ''): err = failure.Failure( error.MissingParameterError( 'Directionality parameter not defined')) return self._createSOAPFault(err, header.provider_nsa) # create DTOs (EROs not supported yet) start_time = xmlhelper.parseXMLTimestamp( criteria.schedule.startTime ) if criteria.schedule.startTime is not None else None end_time = xmlhelper.parseXMLTimestamp(criteria.schedule.endTime) schedule = nsa.Schedule(start_time, end_time) src_stp = helper.createSTP(p2ps.sourceSTP) dst_stp = helper.createSTP(p2ps.destSTP) if p2ps.ero: err = failure.Failure( error.PayloadError('ERO not supported, go away.')) return self._createSOAPFault(err, header.provider_nsa) # if p2ps.parameter: # p = p2ps.parameter[0] # err = failure.Failure ( error.UnsupportedParameter('Unsupported parameter: %s/%s' % (p.type_, p.value) ) ) # return self._createSOAPFault(err, header.provider_nsa) params = [(p.type_, p.value) for p in p2ps.parameter] if p2ps.parameter else None symmetric = p2ps.symmetricPath or False # the p2p service specifies default behaviour as false, but doesn't specify default sd = nsa.Point2PointService(src_stp, dst_stp, p2ps.capacity, p2ps.directionality, symmetric, None, params) crt = nsa.Criteria(criteria.version, schedule, sd) t_delta = time.time() - t_start log.msg('Profile: Reserve request parse time: %s' % round(t_delta, 3), profile=True, system=LOG_SYSTEM) d = self.provider.reserve(header, reservation.connectionId, reservation.globalReservationId, reservation.description, crt) def createReserveAcknowledgement(connection_id): # no reply to / security attrs / trace soap_header_element = helper.createProviderHeader( header.requester_nsa, header.provider_nsa, None, header.correlation_id) reserve_response = nsiconnection.ReserveResponseType(connection_id) reserve_response_element = reserve_response.xml( nsiconnection.reserveResponse) payload = minisoap.createSoapPayload(reserve_response_element, soap_header_element) return payload d.addCallbacks(createReserveAcknowledgement, self._createSOAPFault, errbackArgs=(header.provider_nsa, )) return d