def DELETE(request): """Delete this Room.""" # Make sure required parameters are there try: request.check_required_parameters(path={'roomId': 'int'}) except exceptions.ParameterError as e: return Response(400, e.message) # Instantiate a Room and make sure it exists room = Room.from_primary_key((request.params_path['roomId'], )) if not room.exists(): return Response(404, '{} not found.'.format(room)) # Make sure this user is authorized to delete this Room if not room.google_id_has_at_least(request.google_id, 'EDIT'): return Response(403, 'Forbidden from deleting {}.'.format(room)) # Delete this Room room.delete() # Return this Room return Response(200, 'Successfully deleted {}.'.format(room), room.to_JSON())
def GET(request): """Get this Datacenter's Rooms.""" # Make sure required parameters are there try: request.check_required_parameters(path={'datacenterId': 'int'}) except exceptions.ParameterError as e: return Response(400, e.message) # Instantiate a Datacenter from the database datacenter = Datacenter.from_primary_key( (request.params_path['datacenterId'], )) # Make sure this Datacenter exists if not datacenter.exists(): return Response(404, '{} not found.'.format(datacenter)) # Make sure this user is authorized to view this Datacenter's Rooms if not datacenter.google_id_has_at_least(request.google_id, 'VIEW'): return Response( 403, 'Forbidden from viewing Rooms for {}.'.format(datacenter)) # Get and return the Rooms rooms = Room.query('datacenter_id', datacenter.id) return Response(200, 'Successfully retrieved Rooms for {}.'.format(datacenter), [x.to_JSON() for x in rooms])
def GET(request): """Get this Room.""" # Make sure required parameters are there try: request.check_required_parameters(path={'roomId': 'int'}) except exceptions.ParameterError as e: return Response(400, e.message) # Instantiate a Room from the database room = Room.from_primary_key((request.params_path['roomId'], )) # Make sure this Room exists if not room.exists(): return Response(404, '{} not found.'.format(room)) # Make sure this user is authorized to view this Room if not room.google_id_has_at_least(request.google_id, 'VIEW'): return Response(403, 'Forbidden from retrieving {}.'.format(room)) # Return this Room room.read() return Response(200, 'Successfully retrieved {}.'.format(room), room.to_JSON())
def google_id_has_at_least(self, google_id, authorization_level): """Return True if the user has at least the given auth level over this Tile.""" # Get the Room try: room = Room.from_primary_key((self.room_id,)) except exceptions.RowNotFoundError: return False # Check the Room's Authorization return room.google_id_has_at_least(google_id, authorization_level)
def PUT(request): """Update this Room's name and type.""" # Make sure required parameters are there try: request.check_required_parameters( path={'roomId': 'int'}, body={'room': { 'name': 'string', 'roomType': 'string' }}) except exceptions.ParameterError as e: return Response(400, e.message) # Instantiate a Room from the database room = Room.from_primary_key((request.params_path['roomId'], )) # Make sure this Room exists if not room.exists(): return Response(404, '{} not found.'.format(room)) # Make sure this user is authorized to edit this Room if not room.google_id_has_at_least(request.google_id, 'EDIT'): return Response(403, 'Forbidden from updating {}.'.format(room)) # Update this Room room.name = request.params_body['room']['name'] room.type = request.params_body['room']['roomType'] try: room.update() except exceptions.ForeignKeyError: return Response(400, 'Invalid `roomType` or existing `name`.') # Return this Room return Response(200, 'Successfully updated {}.'.format(room), room.to_JSON())
def POST(request): """Create a new Path that branches off of this Path at the specified tick.""" # Make sure required parameters are there try: request.check_required_parameters( path={'pathId': 'int'}, body={'section': { 'startTick': 'int' }}) except exceptions.ParameterError as e: return Response(400, e.message) # Instantiate the current Path from the database current_path = Path.from_primary_key((request.params_path['pathId'], )) # Make sure the current Path exists if not current_path.exists(): return Response(404, '{} not found.'.format(current_path)) # Make sure this user is authorized to branch off the current Path if not current_path.google_id_has_at_least(request.google_id, 'EDIT'): return Response( 403, 'Forbidden from branching off {}.'.format(current_path)) # Create the new Path new_path = Path(simulation_id=current_path.simulation_id, datetime_created=database.datetime_to_string( datetime.now())) new_path.insert() # Get the current Path's sections and add them to the new Path if they're before the branch current_sections = Section.query('path_id', current_path.id) last_section = None for current_section in current_sections: if current_section.start_tick < request.params_body['section'][ 'startTick'] or current_section.start_tick == 0: new_section = Section(path_id=new_path.id, datacenter_id=current_section.datacenter_id, start_tick=current_section.start_tick) new_section.insert() last_section = current_section # Make a deep copy of the last section's datacenter, its rooms, their tiles, etc. path_parameters = {'simulationId': new_path.simulation_id} # Copy the Datacenter old_datacenter = Datacenter.from_primary_key( (last_section.datacenter_id, )) message = old_datacenter.generate_api_call(path_parameters, request.token) response = Request(message).process() path_parameters['datacenterId'] = response.content['id'] # Create the new last Section, with the IDs of the new Path and new Datacenter if last_section.start_tick != 0: new_section = Section( path_id=new_path.id, datacenter_id=path_parameters['datacenterId'], start_tick=request.params_body['section']['startTick']) new_section.insert() else: last_section.datacenter_id = path_parameters['datacenterId'] last_section.update() # Copy the rest of the Datacenter, starting with the Rooms... old_rooms = Room.query('datacenter_id', old_datacenter.id) for old_room in old_rooms: old_room.datacenter_id = path_parameters['datacenterId'] if old_room.topology_id is None: old_room.topology_id = old_room.id message = old_room.generate_api_call(path_parameters, request.token) response = Request(message).process() path_parameters['roomId'] = response.content['id'] # ... then the Tiles, ... old_tiles = Tile.query('room_id', old_room.id) for old_tile in old_tiles: old_tile.room_id = path_parameters['roomId'] if old_tile.topology_id is None: old_tile.topology_id = old_tile.id message = old_tile.generate_api_call(path_parameters, request.token) response = Request(message).process() path_parameters['tileId'] = response.content['id'] old_objects = Object.query('id', old_tile.object_id) # ... then the Tile's Rack, ... if len(old_objects) == 1 and old_objects[0].type == 'RACK': old_rack = Rack.query('id', old_objects[0].id)[0] if old_rack.topology_id is None: old_rack.topology_id = old_rack.id message = old_rack.generate_api_call(path_parameters, request.token) response = Request(message).process() path_parameters['rackId'] = response.content['id'] # ... then the Rack's Machines ... old_machines = Machine.query('rack_id', old_rack.id) for old_machine in old_machines: old_machine.read() old_machine.rack_id = path_parameters['rackId'] if old_machine.topology_id is None: old_machine.topology_id = old_machine.id message = old_machine.generate_api_call( path_parameters, request.token) response = Request(message).process() path_parameters['machineId'] = response.content['id'] # Return the new Path return Response(200, 'Successfully created {}.'.format(new_path), new_path.to_JSON())
def POST(request): """Add a Room.""" # Make sure required parameters are there try: request.check_required_parameters(path={'datacenterId': 'int'}, body={ 'room': { 'id': 'int', 'datacenterId': 'int', 'roomType': 'string' } }) except exceptions.ParameterError as e: return Response(400, e.message) # Make sure the passed object's datacenter id matches the path datacenter id if request.params_path['datacenterId'] != request.params_body['room'][ 'datacenterId']: return Response(400, 'ID mismatch.') # Instantiate a Datacenter from the database datacenter = Datacenter.from_primary_key( (request.params_path['datacenterId'], )) # Make sure this Datacenter exists if not datacenter.exists(): return Response(404, '{} not found.'.format(datacenter)) # Make sure this user is authorized to edit this Datacenter's Rooms if not datacenter.google_id_has_at_least(request.google_id, 'EDIT'): return Response( 403, 'Forbidden from adding a Room to {}.'.format(datacenter)) # Add a name if not provided if 'name' not in request.params_body['room']: room_count = len(Room.query('datacenter_id', datacenter.id)) request.params_body['room']['name'] = 'Room {}'.format(room_count) # Instantiate a Room room = Room.from_JSON(request.params_body['room']) # Try to insert this Room try: room.insert() except: return Response(400, 'Invalid `roomType` or existing `name`.') # Return this Room room.read() return Response(200, 'Successfully added {}.'.format(room), room.to_JSON())
def POST(request): """Add a Tile.""" # Make sure required parameters are there try: request.check_required_parameters(path={'roomId': 'int'}, body={ 'tile': { 'roomId': 'int', 'positionX': 'int', 'positionY': 'int' } }) except exceptions.ParameterError as e: return Response(400, e.message) if request.params_path['roomId'] != request.params_body['tile']['roomId']: return Response(400, 'ID mismatch') # Instantiate a Room from the database room = Room.from_primary_key((request.params_path['roomId'], )) # Make sure this Room exists if not room.exists(): return Response(404, '{} not found.'.format(room)) # Make sure this user is authorized to edit this Room's Tiles if not room.google_id_has_at_least(request.google_id, 'EDIT'): return Response(403, 'Forbidden from adding Tiles to {}.'.format(room)) # Clean the tile JSON tile_json = request.params_body['tile'] tile_json['objectId'] = None tile_json['objectType'] = None # Instantiate a Tile tile = Tile.from_JSON(tile_json) # Try to insert this Tile try: tile.insert() except exceptions.ForeignKeyError as e: if e.message == 'OccupiedTilePosition': return Response(409, 'Tile position occupied.') elif e.message == 'InvalidTilePosition': return Response( 400, 'Invalid Tile position (new Tiles must neighbor existing Tiles).' ) # Return this Tile tile.read() return Response(200, 'Successfully added {}.'.format(tile), tile.to_JSON())