From 62edcefe9883bdf1fe34c07007e2b614a64ea795 Mon Sep 17 00:00:00 2001 From: Prasanna Santhanam Date: Tue, 10 Sep 2013 12:28:02 +0530 Subject: [PATCH] marvin_refactor: fix marvin build and code generation - generate code using generate/ module but triggered from basedir/marvin - fix the pom to be the same as before, use codegenerator - fix simulator build by removing ConfigDepot bean already injected as part of applicationContext.xml Signed-off-by: Prasanna Santhanam --- tools/marvin/marvin/codegenerator.py | 101 ++++++++++++++++++ .../marvin/marvin/entity/cloudstackentity.py | 25 ----- tools/marvin/marvin/generate/apitoentity.py | 44 +------- tools/marvin/marvin/generate/xmltoapi.py | 48 --------- tools/marvin/pom.xml | 2 +- 5 files changed, 107 insertions(+), 113 deletions(-) create mode 100644 tools/marvin/marvin/codegenerator.py delete mode 100644 tools/marvin/marvin/entity/cloudstackentity.py diff --git a/tools/marvin/marvin/codegenerator.py b/tools/marvin/marvin/codegenerator.py new file mode 100644 index 00000000000..a7360392b39 --- /dev/null +++ b/tools/marvin/marvin/codegenerator.py @@ -0,0 +1,101 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +import os +import sys +from argparse import ArgumentParser +from generate.xmltoapi import codeGenerator +from generate.apitoentity import generate + +def get_api_cmds(): + """ Returns the API cmdlet instances + + @return: instances of all the API commands exposed by CloudStack + """ + namespace = {} + execfile('cloudstackAPI/__init__.py', namespace) + api_classes = __import__('cloudstackAPI', globals().update(namespace), fromlist=['*'], level=-1) + + + cmdlist = map( + lambda f: getattr(api_classes, f), + filter( + lambda t: t.startswith('__') == False, + dir(api_classes) + ) + ) + cmdlist = filter( + lambda g: g is not None, + cmdlist + ) + clslist = map( + lambda g: getattr(g, g.__name__.split('.')[-1] + 'Cmd'), + filter( + lambda h: h.__name__.split('.')[-1] not in ['baseCmd', 'baseResponse', 'cloudstackAPIClient'], + cmdlist + ) + ) + cmdlets = map(lambda t: t(), clslist) + return cmdlets + +if __name__ == "__main__": + parser = ArgumentParser() + parser.add_argument("-o", "--output", dest="output", + help="The path to the generated code entities, default\ + is .") + parser.add_argument("-s", "--specfile", dest="spec", + help="The path and name of the api spec xml file,\ + default is /etc/cloud/cli/commands.xml") + parser.add_argument("-e", "--endpoint", dest="endpoint", + help="The endpoint mgmt server (with open 8096) where\ + apis are discovered, default is localhost") + parser.add_argument("-y", "--entity", dest="entity", action="store_true", + help="Generate entity based classes") + + options = parser.parse_args() + + folder = "." + if options.output is not None: + folder = options.output + apiModule = folder + "/cloudstackAPI" + if not os.path.exists(apiModule): + try: + os.mkdir(apiModule) + except: + print "Failed to create folder %s, due to %s" % (apiModule, + sys.exc_info()) + print parser.print_help() + exit(2) + + apiSpecFile = "/etc/cloud/cli/commands.xml" + if options.spec is not None: + apiSpecFile = options.spec + if not os.path.exists(apiSpecFile): + print "the spec file %s does not exists" % apiSpecFile + print parser.print_help() + exit(1) + + cg = codeGenerator(apiModule) + if options.spec is not None: + cg.generateCodeFromXML(apiSpecFile) + elif options.endpoint is not None: + endpointUrl = 'http://%s:8096/client/api?command=listApis&\ +response=json' % options.endpoint + cg.generateCodeFromJSON(endpointUrl) + + if options.entity: + generate(get_api_cmds()) \ No newline at end of file diff --git a/tools/marvin/marvin/entity/cloudstackentity.py b/tools/marvin/marvin/entity/cloudstackentity.py deleted file mode 100644 index b7091de44d5..00000000000 --- a/tools/marvin/marvin/entity/cloudstackentity.py +++ /dev/null @@ -1,25 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -cloudstack_version = "4.2.0" - -class CloudStackEntity(object): - - __version__ = cloudstack_version - - def getVersion(self): - return self.__version__ diff --git a/tools/marvin/marvin/generate/apitoentity.py b/tools/marvin/marvin/generate/apitoentity.py index 0be5d9aa81c..90b9eb279d5 100644 --- a/tools/marvin/marvin/generate/apitoentity.py +++ b/tools/marvin/marvin/generate/apitoentity.py @@ -38,45 +38,14 @@ LICENSE = """# Licensed to the Apache Software Foundation (ASF) under one # under the License. """ -def get_api_cmds(): - """ Returns the API cmdlet instances - - @return: instances of all the API commands exposed by CloudStack - """ - namespace = {} - execfile('cloudstackAPI/__init__.py', namespace) - api_classes = __import__('cloudstackAPI', globals().update(namespace), fromlist=['*'], level=-1) - - - cmdlist = map( - lambda f: getattr(api_classes, f), - filter( - lambda t: t.startswith('__') == False, - dir(api_classes) - ) - ) - cmdlist = filter( - lambda g: g is not None, - cmdlist - ) - clslist = map( - lambda g: getattr(g, g.__name__.split('.')[-1] + 'Cmd'), - filter( - lambda h: h.__name__.split('.')[-1] not in ['baseCmd', 'baseResponse', 'cloudstackAPIClient'], - cmdlist - ) - ) - cmdlets = map(lambda t: t(), clslist) - return cmdlets - -def get_entity_action_map(): +def get_entity_action_map(apimodules): """ Inspect cloudstack api and return a map of the Entity against the actions along with the required arguments to make the action call @return: Dictionary of Entity { "verb" : [required] } eg: VirtualMachine { "deploy" : [templateid, serviceoffering, zoneid, etc] } """ - cmdlets = sorted(filter(lambda api: api.__class__.__name__ not in skip_list(), get_api_cmds()), + cmdlets = sorted(filter(lambda api: api.__class__.__name__ not in skip_list(), apimodules), key=lambda k: get_verb_and_entity(k)[1]) entities = {} @@ -109,13 +78,14 @@ def write(entity_or_factory, module): writer.write(LICENSE) writer.write(entity_or_factory.__str__()) -def generate(entities): +def generate(api): """ Writes the collected entity classes - @param entities: dictionary of entities and the verbs acting on them + @param api: api cmdlet modules read from cloudstackAPI/__init__.py @return: """ + entities = get_entity_action_map(api) for entity, actions in entities.iteritems(): e = Entity() f = Factory() @@ -125,7 +95,3 @@ def generate(entities): write(e, module='entity') write(f, module='factory') - -if __name__ == '__main__': - entities = get_entity_action_map() - generate(entities) diff --git a/tools/marvin/marvin/generate/xmltoapi.py b/tools/marvin/marvin/generate/xmltoapi.py index f8e573aa065..5cc76daa751 100644 --- a/tools/marvin/marvin/generate/xmltoapi.py +++ b/tools/marvin/marvin/generate/xmltoapi.py @@ -438,51 +438,3 @@ class codeGenerator(object): def getText(elements): return elements[0].childNodes[0].nodeValue.strip() -if __name__ == "__main__": - parser = ArgumentParser() - parser.add_argument("-o", "--output", dest="output", - help="The path to the generated code entities, default\ - is .") - parser.add_argument("-s", "--specfile", dest="spec", - help="The path and name of the api spec xml file,\ - default is /etc/cloud/cli/commands.xml") - parser.add_argument("-e", "--endpoint", dest="endpoint", - help="The endpoint mgmt server (with open 8096) where\ - apis are discovered, default is localhost") - parser.add_argument("-y", "--entity", dest="entity", action="store_true", - help="Generate entity based classes") - - options = parser.parse_args() - - folder = "." - if options.output is not None: - folder = options.output - apiModule = folder + "/cloudstackAPI" - if not os.path.exists(apiModule): - try: - os.mkdir(apiModule) - except: - print "Failed to create folder %s, due to %s" % (apiModule, - sys.exc_info()) - print parser.print_help() - exit(2) - - apiSpecFile = "/etc/cloud/cli/commands.xml" - if options.spec is not None: - apiSpecFile = options.spec - if not os.path.exists(apiSpecFile): - print "the spec file %s does not exists" % apiSpecFile - print parser.print_help() - exit(1) - - cg = codeGenerator(apiModule) - if options.spec is not None: - cg.generateCodeFromXML(apiSpecFile) - elif options.endpoint is not None: - endpointUrl = 'http://%s:8096/client/api?command=listApis&\ -response=json' % options.endpoint - cg.generateCodeFromJSON(endpointUrl) - - if options.entity: - entities = get_entity_action_map() - generate(entities, "entity") diff --git a/tools/marvin/pom.xml b/tools/marvin/pom.xml index 872921de8e3..25909b340e0 100644 --- a/tools/marvin/pom.xml +++ b/tools/marvin/pom.xml @@ -55,7 +55,7 @@ ${basedir}/marvin python - generate/xmltoapi.py + codegenerator.py -s ${basedir}/commands.xml