def makeResourceFromClass(component_class, params): """ Create a new resource representation from the specified component class and parameter dictionary and store it on disk. The parameters need to look something like this: { "reource creation_params" : { "suggested_name" : "my_twitter", "desc" : "Our Twitter stream" }, "params" : { "user" : "AccountName", "password" : "some password" }, "positional_params" : [ "user" ] # Optional } The method performs sanity checking on the supplied parameters and also fills in default values where available. @param component_class: A class (not instance) derived from BaseComponent. @type component_class: BaseComponent or derived. @param params: The resource parameters provided by the client. Needs to contain at least a 'params' dictionary or a 'resource_creation_dictionary'. Can contain both. @type params: dict @return: Success message in form of dictionary that contains "status", "name" and "uri" fields. @rtype: dict @raise RestxException: If the resource creation failed or there was a problem with the provided parameters. """ # We get the meta data (parameter definition) from the component component = component_class() component_params_def = component.getMetaData() component_params_def = languageStructToPython(component, component_params_def) # # First we check whether there are any unknown parameters specified # on the top level. # if type(params) is not dict: raise RestxException( "Malformed resource parameter definition. Has to be JSON dictionary." ) for k in params.keys(): if k not in ['params', 'resource_creation_params']: raise RestxException( "Malformed resource parameter definition. Unknown key: %s" % k) # # Check whether there are unknown parameters in the 'param' or 'resource_creation_params' section. # provided_params = params.get('params') if not provided_params: # If no parameters were provided at all, we create them as # an empty dictionary. We need something here to be able # to merge some defaults into it later on. provided_params = dict() params['params'] = provided_params provided_resource_creation_params = params.get('resource_creation_params') paramSanityCheck(provided_params, component_params_def['params'], 'params') paramSanityCheck(provided_resource_creation_params, component_params_def['resource_creation_params'], 'resource_creation_params') # Before storing the parameters, we make sure they are converted to the # types that have been specified convertTypes(component_params_def['params'], provided_params) # The parameters passed the sanity checks. We can now create the resource definition. suggested_name = provided_resource_creation_params['suggested_name'] resource_uri = settings.PREFIX_RESOURCE + "/" + suggested_name resource_name = suggested_name # TODO: Should check if the resource exists already... params['code_uri'] = component.getCodeUri( ) # Need a reference to the code that this applies to # Some parameters are optional. If they were not supplied, # we need to add their default values. fillDefaults(component_params_def['params'], provided_params) fillDefaults(component_params_def['resource_creation_params'], provided_resource_creation_params) # Storage for a resource contains a private and public part. The public part is what # any user of the resource can see: URI, name and description. In the private part we # store whatever was provided here during resource creation. It contains the information # we need to instantiate a running resource. resource_def = { "private": params, "public": { "uri": resource_uri, "name": resource_name, "desc": provided_resource_creation_params['desc'] } } # Storage to our 'database'. STORAGE_OBJECT.writeResourceToStorage(resource_name, resource_def) # Send a useful message back to the client. success_body = { "status": "created", "name": resource_name, # Is returned, because server could have chosen different name "uri": resource_uri } return success_body
def makeResourceFromComponentObject(component, params, specialized=None, partial_resource_name=None): """ Create a new resource representation from the specified component class and parameter dictionary and store it on disk. The parameters need to look something like this: { "reource creation_params" : { "suggested_name" : "my_twitter", "desc" : "Our Twitter stream", "specialized" : false }, "params" : { "user" : "AccountName", "password" : "some password" }, } The method performs sanity checking on the supplied parameters and also fills in default values where available. @param component_class: A class (not instance) derived from BaseComponent. @type component_class: BaseComponent or derived. @param params: The resource parameters provided by the client. Needs to contain at least a 'params' dictionary or a 'resource_creation_dictionary'. Can contain both. @type params: dict @param specialized: If this resource should be based on a partial resource definition (specialized code) then we are given the resource definition dictionary of the partial resource here. Otherwise, this is None. This is only permitted if the resource-creation-parameters do NOT set the 'specialized' flag. That flag indicates that we want to create a new specialized component resource, not a resource based on a specialized component. @type specialized: dict @param partial_resource_name: Name of the partial resource from which we have the specialized (partial resource) definition. @type partial_resource_name: string @return: Success message in form of dictionary that contains "status", "name" and "uri" fields. @rtype: dict @raise RestxException: If the resource creation failed or there was a problem with the provided parameters. """ # We get the meta data (parameter definition) from the component component_params_def = component.getMetaData() component_params_def = languageStructToPython(component, component_params_def) if specialized: # Do an overwrite and merge with the specialized component (partial resource # data). This may modify the description and suggested name defaults. component_params_def = specializedOverwrite(component_params_def, specialized) # # First we check whether there are any unknown parameters specified # on the top level. # if type(params) is not dict: raise RestxException("Malformed resource parameter definition. Has to be JSON dictionary.") for k in params.keys(): if k not in [ 'params', 'resource_creation_params' ]: raise RestxBadRequestException("Malformed resource parameter definition. Unknown key: %s" % k) # Check whether there are unknown parameters in the 'param' or 'resource_creation_params' section. provided_params = params.get('params') if not provided_params: # If no parameters were provided at all, we create them as # an empty dictionary. We need something here to be able # to merge some defaults into it later on. provided_params = dict() params['params'] = provided_params # Merge with any parameters provided by a partial resource we may use as base # If there are doubles (something was provided with the create request, which was # also already defined in the partial base resource) then we are simply ignoring # the provided value and overwrite them with what was defined in the partial # resource. specialized_params = None if specialized: try: specialized_params = specialized['private']['params'] provided_params.update(specialized_params) except: pass provided_resource_creation_params = params.get('resource_creation_params') # Note the difference between 'specialized' and the 'make_specialized_component' flag: # If a 'specialized' parameter is provided then we know that we want to create a new # usable resource, based on a specialized component resource. However, if the # resource-creation-parameters contain the 'specialized' flag, this means that we # just want to create the specialized component resource (the base resource). Those # two things are mutually exclusive. if provided_resource_creation_params: make_specialized_component = provided_resource_creation_params.get('specialized', False) if make_specialized_component and specialized: raise RestxException("Cannot create resource with specializec component resource as base AND set 'specialized' flag at the same time.") else: make_specialized_component = False paramSanityCheck(provided_params, component_params_def['params'], 'params', make_specialized_component) paramSanityCheck(provided_resource_creation_params, component_params_def['resource_creation_params'], 'resource_creation_params') # Before storing the parameters, we make sure they are converted to the # types that have been specified convertTypes(component_params_def['params'], provided_params) # The parameters passed the sanity checks. We can now create the resource definition. suggested_name = provided_resource_creation_params['suggested_name'] resource_uri = (settings.PREFIX_RESOURCE if not make_specialized_component else settings.PREFIX_SPECIALIZED) + "/" + suggested_name resource_name = suggested_name # TODO: Should check if the resource exists already... params['code_uri'] = component.getCodeUri() # Need a reference to the code that this applies to # Some parameters are optional. If they were not supplied, # we need to add their default values. However, we only do this # when we create a normal resource. For specialized component # resources, we don't want to set those default values, since # otherwise they appear as 'set and unmodifiable' for those # who want to create an actual resource based on a specialized # component resource. if not make_specialized_component: fillDefaults(component_params_def['params'], provided_params) fillDefaults(component_params_def['resource_creation_params'], provided_resource_creation_params) # After all parameters have been dealt with, we now # should remove all the parameters that came from a partial resource # if we are creating a component based on that. private_params = params.get('params') if specialized_params and private_params: for key in specialized_params.keys(): if key in private_params: del private_params[key] # Storage for a resource contains a private and public part. The public part is what # any user of the resource can see: URI, name and description. In the private part we # store whatever was provided here during resource creation. It contains the information # we need to instantiate a running resource. resource_def = { "private" : params, "public" : { "uri" : resource_uri, "name" : resource_name, "desc" : provided_resource_creation_params['desc'] } } if specialized: resource_def['extends'] = partial_resource_name del resource_def['private']['code_uri'] # Storage to our 'database'. STORAGE_OBJECT.writeResourceToStorage(resource_name, resource_def, make_specialized_component) # Send a useful message back to the client. success_body = { "status" : "created", "name" : resource_name, # Is returned, because server could have chosen different name "uri" : resource_uri } return success_body
def makeResourceFromClass(component_class, params): """ Create a new resource representation from the specified component class and parameter dictionary and store it on disk. The parameters need to look something like this: { "reource creation_params" : { "suggested_name" : "my_twitter", "desc" : "Our Twitter stream" }, "params" : { "user" : "AccountName", "password" : "some password" }, "positional_params" : [ "user" ] # Optional } The method performs sanity checking on the supplied parameters and also fills in default values where available. @param component_class: A class (not instance) derived from BaseComponent. @type component_class: BaseComponent or derived. @param params: The resource parameters provided by the client. Needs to contain at least a 'params' dictionary or a 'resource_creation_dictionary'. Can contain both. @type params: dict @return: Success message in form of dictionary that contains "status", "name" and "uri" fields. @rtype: dict @raise RestxException: If the resource creation failed or there was a problem with the provided parameters. """ # We get the meta data (parameter definition) from the component component = component_class() component_params_def = component.getMetaData() component_params_def = languageStructToPython(component, component_params_def) # # First we check whether there are any unknown parameters specified # on the top level. # if type(params) is not dict: raise RestxException("Malformed resource parameter definition. Has to be JSON dictionary.") for k in params.keys(): if k not in [ 'params', 'resource_creation_params' ]: raise RestxException("Malformed resource parameter definition. Unknown key: %s" % k) # # Check whether there are unknown parameters in the 'param' or 'resource_creation_params' section. # provided_params = params.get('params') if not provided_params: # If no parameters were provided at all, we create them as # an empty dictionary. We need something here to be able # to merge some defaults into it later on. provided_params = dict() params['params'] = provided_params provided_resource_creation_params = params.get('resource_creation_params') paramSanityCheck(provided_params, component_params_def['params'], 'params') paramSanityCheck(provided_resource_creation_params, component_params_def['resource_creation_params'], 'resource_creation_params') # Before storing the parameters, we make sure they are converted to the # types that have been specified convertTypes(component_params_def['params'], provided_params) # The parameters passed the sanity checks. We can now create the resource definition. suggested_name = provided_resource_creation_params['suggested_name'] resource_uri = settings.PREFIX_RESOURCE + "/" + suggested_name resource_name = suggested_name # TODO: Should check if the resource exists already... params['code_uri'] = component.getCodeUri() # Need a reference to the code that this applies to # Some parameters are optional. If they were not supplied, # we need to add their default values. fillDefaults(component_params_def['params'], provided_params) fillDefaults(component_params_def['resource_creation_params'], provided_resource_creation_params) # Storage for a resource contains a private and public part. The public part is what # any user of the resource can see: URI, name and description. In the private part we # store whatever was provided here during resource creation. It contains the information # we need to instantiate a running resource. resource_def = { "private" : params, "public" : { "uri" : resource_uri, "name" : resource_name, "desc" : provided_resource_creation_params['desc'] } } # Storage to our 'database'. STORAGE_OBJECT.writeResourceToStorage(resource_name, resource_def) # Send a useful message back to the client. success_body = { "status" : "created", "name" : resource_name, # Is returned, because server could have chosen different name "uri" : resource_uri } return success_body