diff options
84 files changed, 8025 insertions, 123 deletions
diff --git a/docs/conf.py b/docs/conf.py new file mode 100644 index 0000000..3c4453e --- /dev/null +++ b/docs/conf.py @@ -0,0 +1 @@ +from docs_conf.conf import * diff --git a/docs/conf.yaml b/docs/conf.yaml new file mode 100644 index 0000000..e2c35e6 --- /dev/null +++ b/docs/conf.yaml @@ -0,0 +1,3 @@ +--- +project_cfg: opnfv +project: parser diff --git a/docs/index.rst b/docs/index.rst new file mode 100644 index 0000000..b2c3b5d --- /dev/null +++ b/docs/index.rst @@ -0,0 +1,17 @@ +.. This work is licensed under a Creative Commons Attribution 4.0 +.. International License. +.. SPDX-License-Identifier: CC-BY-4.0 +.. (c) Open Platform for NFV Project, Inc. and its contributors + +.. _parser: + +====== +Parser +====== + +.. toctree:: + :maxdepth: 2 + + release/installation/index + release/release-notes/index + release/userguide/index diff --git a/docs/release/release-notes/release-notes.rst b/docs/release/release-notes/release-notes.rst index 3c1dc70..1244a65 100644 --- a/docs/release/release-notes/release-notes.rst +++ b/docs/release/release-notes/release-notes.rst @@ -12,19 +12,25 @@ This document provides the release notes for <Danube Release> of <Parser>. Version history --------------- -+--------------------+--------------------+--------------------+--------------------+ -| **Date** | **Ver.** | **Author** | **Comment** | -| | | | | -+--------------------+--------------------+--------------------+--------------------+ -| 2017-03-06 | 1.0 | Howard Huang | Danube Release | -| | | | | -+--------------------+--------------------+--------------------+--------------------+ -| 2017-09-25 | 2.0 | Shang Xiaodong | Euphrates release | -| | | | | -+--------------------+--------------------+--------------------+--------------------+ -| | | | | -| | | | | -+--------------------+--------------------+--------------------+--------------------+ ++--------------------+--------------------+--------------------+----------------------+ +| **Date** | **Ver.** | **Author** | **Comment** | +| | | | | ++--------------------+--------------------+--------------------+----------------------+ +| 2016-04-20 | 0.5 | Howard Huang | Brahmaputra Release | +| | | | | ++--------------------+--------------------+--------------------+----------------------+ +| 2016-09-19 | 1.0 | Howard Huang | Colorado Release | +| | | | | ++--------------------+--------------------+--------------------+----------------------+ +| 2017-03-06 | 2.0 | Howard Huang | Danube Release | +| | | | | ++--------------------+--------------------+--------------------+----------------------+ +| 2017-09-25 | 5.0 | Shang Xiaodong | Euphrates release | +| | 0.5 ONAP | | | ++--------------------+--------------------+--------------------+----------------------+ +| 2018-04-20 | 6.0 | Shang Xiaodong | Fraser release | +| | 1.0 ONAP | | | ++--------------------+--------------------+--------------------+----------------------+ Important notes =============== @@ -39,7 +45,8 @@ Summary OPNFV Parser Danube release has provides four submodules to serve as translation/prevalidation tools: tosca2heat, yang2tosca, policy2tosca, and verigraph. Specifically, tosca2heat module provides an integration of OpenStack tosca-parser and heat-translater -upstream projects 0.7 release with additional Parser unique features. +upstream projects 0.7 release with additional Parser unique features, and includes nfv-toscaparser + and nfv-heattranslaotor for ONAP community. Release Data @@ -59,15 +66,155 @@ Release Data | | tion tooling | +--------------------------------------+--------------------------------------+ +Fraser Release Data +----------------------- + ++--------------------------------------+--------------------------------+ +| **Project** | OPNFV Parer | +| | | ++--------------------------------------+--------------------------------+ +| **Repo/tag** | Parser/6.0.0 | +| | | +| | | ++--------------------------------------+--------------------------------+ +| **Bottlenecks Docker image tag** | * 6.0.0 | +| | | +| | | ++--------------------------------------+--------------------------------+ +| **Release designation** | * 6.0.0 | +| | | +| | | ++--------------------------------------+--------------------------------+ +| **Release date** | * Apr 20th 2018 | +| | | +| | | ++--------------------------------------+--------------------------------+ +| **Purpose of the delivery** | Fraser stable release | +| | | +| | OPNFV Template Translation/ | +| | Prevalidation tooling | ++--------------------------------------+--------------------------------+ + +Euphrates Release Data +----------------------- + ++--------------------------------------+--------------------------------+ +| **Project** | OPNFV Parer | +| | | ++--------------------------------------+--------------------------------+ +| **Repo/tag** | Parser/5.0.0 | +| | | +| | | ++--------------------------------------+--------------------------------+ +| **Bottlenecks Docker image tag** | * 5.0.0 | +| | | +| | | ++--------------------------------------+--------------------------------+ +| **Release designation** | * 5.0.0 | +| | | +| | | ++--------------------------------------+--------------------------------+ +| **Release date** | * Sept 25th 2017 | +| | | +| | | ++--------------------------------------+--------------------------------+ +| **Purpose of the delivery** | Euphrates stable release | +| | | +| | OPNFV Template Translation/ | +| | Prevalidation tooling | ++--------------------------------------+--------------------------------+ + +Danube Release Data +----------------------- + ++--------------------------------------+--------------------------------+ +| **Project** | OPNFV Parer | +| | | ++--------------------------------------+--------------------------------+ +| **Repo/tag** | Parser/danube.2.0 | +| | | ++--------------------------------------+--------------------------------+ +| **Bottlenecks Docker image tag** | * danube.2.0 | +| | | +| | | ++--------------------------------------+--------------------------------+ +| **Release designation** | * Danube 2.0 | +| | | +| | | ++--------------------------------------+--------------------------------+ +| **Release date** | * March 6st 2017 | +| | | +| | | ++--------------------------------------+--------------------------------+ +| **Purpose of the delivery** | Danube stable release | +| | | +| | OPNFV Template Translation/ | +| | Prevalidation tooling | ++--------------------------------------+--------------------------------+ + +Colorado Release Data +----------------------- + ++--------------------------------------+--------------------------------+ +| **Project** | OPNFV Parer | +| | | ++--------------------------------------+--------------------------------+ +| **Repo/tag** | Parser/colorado.1.0 | +| | | ++--------------------------------------+--------------------------------+ +| **Bottlenecks Docker image tag** | * colorado.1.0 | +| | | ++--------------------------------------+--------------------------------+ +| **Release designation** | * Colorado 1.0 | +| | | ++--------------------------------------+--------------------------------+ +| **Release date** | * September 22 2016 | +| | | ++--------------------------------------+--------------------------------+ +| **Purpose of the delivery** | Colorado stable release | +| | | +| | OPNFV Template Translation/ | +| | Prevalidation tooling | ++--------------------------------------+--------------------------------+ + +Bramaputra Release Data +----------------------- + ++--------------------------------------+--------------------------------+ +| **Project** | OPNFV Parer | +| | | ++--------------------------------------+--------------------------------+ +| **Repo/tag** | Parser/brahmaputra.1.0 | +| | | ++--------------------------------------+--------------------------------+ +| **Bottlenecks Docker image tag** | * brahmaputra.1.0 | +| | | ++--------------------------------------+--------------------------------+ +| **Release designation** | * Brahmaputra 1.0 | +| | | ++--------------------------------------+--------------------------------+ +| **Release date** | * February 25 2016 | +| | | ++--------------------------------------+--------------------------------+ +| **Purpose of the delivery** | Brahmaputra stable release | +| | | +| | OPNFV Template Translation/ | +| | Prevalidation tooling | ++--------------------------------------+--------------------------------+ + Version change ^^^^^^^^^^^^^^ Module version changes ~~~~~~~~~~~~~~~~~~~~~~ -- OpenStack tosca-parser and heat-translator have changed from 0.6 to 0.7 +- OpenStack tosca-parser and heat-translator have changed from 0.8 to 0.9 + +- Parseer support aarch64 + +- update verigraph module -- new verigraph module +- Release 0.5 and 1.0 for ONAP community - no feature changes in yang2tosca and policy2tosca since Colorado Release. @@ -78,11 +225,9 @@ Document version changes Reason for version ^^^^^^^^^^^^^^^^^^ + Feature additions ~~~~~~~~~~~~~~~~~ -<STATE ADDED FEATURES BY REFERENCE TO JIRA> - -<EXAMPLE>: **JIRA BACK-LOG:** @@ -199,6 +344,7 @@ Known Limitations, Issues and Workarounds System Limitations ^^^^^^^^^^^^^^^^^^ +None @@ -229,11 +375,9 @@ Workarounds Test Result =========== -<STATE THE QA COVERAGE AND RESULTS> -<EXAMPLE>: -Fuel@OPNFV Arno RC2 has undergone QA test runs with the following results: +Parser test with functest runs with the following results: +--------------------------------------+--------------------------------------+ | **TEST-SUITE** | **Results:** | @@ -254,6 +398,12 @@ References ========== -For more information on the OPNFV Danube release, please see: + - WIKI project page: https://wiki.opnfv.org/display/parser + + - Parser jira page: https://jira.opnfv.org/secure/RapidBoard.jspa?rapidView=121&useStoredSettings=true + + - Parser repo: https://git.opnfv.org/cgit/parser + + - Parser CI dashboard: https://build.opnfv.org/ci/view/parser -http://opnfv.org/danube + - Parser IRC chanel: #opnfv-parser diff --git a/docs/release/userguide/feature.userguide.rst b/docs/release/userguide/feature.userguide.rst index 219bc0e..4ad4f22 100644 --- a/docs/release/userguide/feature.userguide.rst +++ b/docs/release/userguide/feature.userguide.rst @@ -7,6 +7,11 @@ Parser tosca2heat Execution =========================== +nfv-heattranslator +------------------- + + There only one way to call nfv-heattranslator service: CLI. + Step 1: Change directory to where the tosca yaml files are present, example is below with vRNC definiton. @@ -29,34 +34,156 @@ Example: heat-translator --template-file=vRNC.yaml \ --template-type=tosca --output-file=vRNC_hot.yaml -**Notes**: heat-translator will call class of ToscaTemplate in tosca-parser firstly to validate and -parse input yaml file, then tranlate the file into hot file, if you only want to validate or -check the input file and don't want to translate, please use tosaca-parser as following: +**Notes**: nfv-heattranslator will call class of ToscaTemplate in nfv-toscaparser firstly to validate and +parse input yaml file, then tranlate the file into hot file. + + +nfv-toscaparser +---------------- + +Implementation of nfv-toscaparser derived from openstack tosca parser is based on the following OASIS specification: + TOSCA Simple Profile YAML 1.2 Referecne http://docs.oasis-open.org/tosca/TOSCA-Simple-Profile-YAML/v1.2/TOSCA-Simple-Profile-YAML-v1.2.html + TOSCA Simple Profile YAML NFV 1.0 Referecne http://docs.oasis-open.org/tosca/tosca-nfv/v1.0/tosca-nfv-v1.0.html + +There are three ways to call nfv-toscaparser service, Python Lib ,CLI and REST API. + +CLI +**** +Using cli, which is used to validate tosca simple based service template. It can be used as: .. code-block:: bash - tosca-parser --template-file=<path to the YAML template> [--nrpv] [--debug] - or - tosca-parser --template-file=<path to the CSAR zip file> [--nrpv] [--debug] - or - tosca-parser --template-file=<URL to the template or CSAR> [--nrpv] [--debug] - options: - --nrpv Ignore input parameter validation when parse template. - --debug debug mode for print more details other than raise exceptions when errors happen + tosca-parser --template-file=<path to the YAML template> [--nrpv] [--debug] + tosca-parser --template-file=<path to the CSAR zip file> [--nrpv] [--debug] + tosca-parser --template-file=<URL to the template or CSAR> [--nrpv] [--debug] -Example: + options: + --nrpv Ignore input parameter validation when parse template. + --debug debug mode for print more details other than raise exceptions when errors happen + + +Library(Python) +**************** + +Using api, which is used to parse and get the result of service template. it can be used as: .. code-block:: bash - tosca-parser --template-file=vRNC.yaml --nrpv + ToscaTemplate(path=None, parsed_params=None, a_file=True, yaml_dict_tpl=None, + sub_mapped_node_template=None, + no_required_paras_valid=False, debug=False) + +REST API +********* + +Using RESTfual API, which are listed as following: + +List template versions +######################## + +PATH: /v1/template_versions +METHOD: GET +Decription: Lists all supported tosca template versions. + +Response Codes + +Success +200 - OK Request was successful. + +Error + +400 - Bad Request Some content in the request was invalid. +404 - Not Found The requested resource could not be found. +500 - Internal Server Error Something went wrong inside the service. This should not happen usually. +If it does happen, it means the server has experienced some serious problems. -Parser tosca2heat References -============================ -Refer two upstream components: - https://github.com/openstack/tosca-parser/blob/master/doc/source/usage.rst - https://github.com/openstack/heat-translator/blob/master/doc/source/usage.rst +Request Parameters +No +Response Parameters + +template_versions array A list of tosca template version object each describes the type name and + version information for a template version. + + +Validates a service template +############################# + +PATH: /v1/validate +METHOD: POST +Decription: Validate a service template. + +Response Codes +Success +200 - OK Request was successful. + +Error + +400 - Bad Request Some content in the request was invalid. +500 - Internal Server Error Something went wrong inside the service. This should not happen usually. + If it does happen, it means the server has experienced some serious problems. +Request Parameters +environment (Optional) object A JSON environment for the template service. +environment_files (Optional) object An ordered list of names for environment files found in the files dict. +files (Optional) object +Supplies the contents of files referenced in the template or the environment. + +The value is a JSON object, where each key is a relative or absolute URI which serves as the name of + a file, and the associated value provides the contents of the file. The following code shows the + general structure of this parameter. + +{ ... + "files": { + "fileA.yaml": "Contents of the file", + "file:///usr/fileB.template": "Contents of the file", + "http://example.com/fileC.template": "Contents of the file" + } +... +} +ignore_errors (Optional) string List of comma separated error codes to ignore. +show_nested (Optional) boolean Set to true to include nested template service in the list. +template (Optional) object +The service template on which to perform the operation. + +This parameter is always provided as a string in the JSON request body. The content of the string is + a JSON- or YAML-formatted service template. For example: + +"template": { + "tosca_definitions_version": "tosca_simple_yaml_1_0", + ... +} +This parameter is required only when you omit the template_url parameter. If you specify both +parameters, this value overrides thetemplate_url parameter value. + +template_url (Optional) string A URI to the location containing the service template on which to +perform the operation. See the description of the template parameter for information about the +expected template content located at the URI. This parameter is only required when you omit the +template parameter. If you specify both parameters, this parameter is ignored. + +Request Example +{ + "template_url": "/PATH_TO_TOSCA_TEMPLATES/HelloWord_Instance.csar" +} + +Response Parameters +Description string The description specified in the template. +Error Information (Optional) string Error information + +Parse a service template +######################### + +PATH: /v1/validate +METHOD: POST +Decription: Validate a service template. +Response Code: same as "Validates a service template" +Request Parameters: same as "Validates a service template" +Response Parameters +Description string The description specified in the template. +Input parameters object Input parameter list. +Service Template object Service template body +Output parameters object Input parameter list. +Error Information (Optional) string Error information Parser yang2tosca Execution @@ -97,9 +224,6 @@ Example: cat example_tosca.yaml - - - Parser policy2tosca Execution ============================= diff --git a/docs/requirements.txt b/docs/requirements.txt new file mode 100644 index 0000000..9fde2df --- /dev/null +++ b/docs/requirements.txt @@ -0,0 +1,2 @@ +lfdocs-conf +sphinx_opnfv_theme diff --git a/tosca2heat/tosca-parser/toscaparser/common/exception.py b/tosca2heat/tosca-parser/toscaparser/common/exception.py index 67a9f7f..d36a714 100644 --- a/tosca2heat/tosca-parser/toscaparser/common/exception.py +++ b/tosca2heat/tosca-parser/toscaparser/common/exception.py @@ -207,10 +207,14 @@ class ExceptionCollector(object): @staticmethod def removeException(exception_type): - if ExceptionCollector.collecting and ExceptionCollector.exceptions: + # if ExceptionCollector.collecting and ExceptionCollector.exceptions: + if ExceptionCollector.exceptions: + tmp_exceptions = [] for i, e in enumerate(ExceptionCollector.exceptions): - if isinstance(e, exception_type): - del ExceptionCollector.exceptions[i] + if not isinstance(e, exception_type): + tmp_exceptions.append(e) + # del ExceptionCollector.exceptions[i] + ExceptionCollector.exceptions = tmp_exceptions @staticmethod def exceptionsCaught(): diff --git a/tosca2heat/tosca-parser/toscaparser/elements/capabilitytype.py b/tosca2heat/tosca-parser/toscaparser/elements/capabilitytype.py index 23c5afc..c37aa9d 100644 --- a/tosca2heat/tosca-parser/toscaparser/elements/capabilitytype.py +++ b/tosca2heat/tosca-parser/toscaparser/elements/capabilitytype.py @@ -35,7 +35,7 @@ class CapabilityTypeDef(StatefulEntityType): parent_properties = {} if self.parent_capabilities: for type, value in self.parent_capabilities.items(): - parent_properties[type] = value.get('properties') + parent_properties[type] = value.get('properties', {}) if self.properties: for prop, schema in self.properties.items(): properties.append(PropertyDef(prop, None, schema)) diff --git a/tosca2heat/tosca-parser/toscaparser/elements/tosca_type_validation.py b/tosca2heat/tosca-parser/toscaparser/elements/tosca_type_validation.py index 89a6a03..8b49f48 100644 --- a/tosca2heat/tosca-parser/toscaparser/elements/tosca_type_validation.py +++ b/tosca2heat/tosca-parser/toscaparser/elements/tosca_type_validation.py @@ -49,12 +49,12 @@ class TypeValidation(object): for name in custom_type: if name not in self.ALLOWED_TYPE_SECTIONS: ExceptionCollector.appendException( - UnknownFieldError(what='Template ' + (self.import_def), + UnknownFieldError(what='Template ' + str(self.import_def), field=name)) def _validate_type_version(self, version): if version not in self.VALID_TEMPLATE_VERSIONS: ExceptionCollector.appendException( InvalidTemplateVersion( - what=version + ' in ' + self.import_def, + what=version + ' in ' + str(self.import_def), valid_versions=', '. join(self.VALID_TEMPLATE_VERSIONS))) diff --git a/tosca2heat/tosca-parser/toscaparser/shell.py b/tosca2heat/tosca-parser/toscaparser/shell.py index 88c7473..c024d1e 100644 --- a/tosca2heat/tosca-parser/toscaparser/shell.py +++ b/tosca2heat/tosca-parser/toscaparser/shell.py @@ -53,7 +53,7 @@ class ParserShell(object): required=True, help=_('YAML template or CSAR file to parse.')) - parser.add_argument('-nrpv', dest='no_required_paras_check', + parser.add_argument('--nrpv', dest='no_required_paras_check', action='store_true', default=False, help=_('Ignore input parameter validation ' 'when parse template.')) @@ -97,9 +97,10 @@ class ParserShell(object): else: raise e - version = tosca.version if tosca else "unknown" - if tosca and tosca.version: - print("\nversion: " + version) + if tosca and hasattr(tosca, 'version'): + print("\nversion: " + tosca.version) + else: + print("\nversion: " + "unknown") if tosca and hasattr(tosca, 'description'): description = tosca.description diff --git a/tosca2heat/tosca-parser/toscaparser/tests/data/custom_types/invalid_type.yaml b/tosca2heat/tosca-parser/toscaparser/tests/data/custom_types/invalid_type.yaml new file mode 100644 index 0000000..4d3a0b0 --- /dev/null +++ b/tosca2heat/tosca-parser/toscaparser/tests/data/custom_types/invalid_type.yaml @@ -0,0 +1,8 @@ +tosca_definitions_version: tosca_simple_yaml_1_1 + +annotation_types: + org.openecomp.annotations.Source: + description: Indicates the origin source of an input + properties: + source_type: + type: string diff --git a/tosca2heat/tosca-parser/toscaparser/tests/data/test_import_invalid_type.yaml b/tosca2heat/tosca-parser/toscaparser/tests/data/test_import_invalid_type.yaml new file mode 100644 index 0000000..f2c1876 --- /dev/null +++ b/tosca2heat/tosca-parser/toscaparser/tests/data/test_import_invalid_type.yaml @@ -0,0 +1,11 @@ +tosca_definitions_version: tosca_simple_yaml_1_1 + +imports: + - invalid: custom_types/invalid_type.yaml + +description: Test to import a template with an invalid type. + +topology_template: + node_templates: + test: + type: tosca.nodes.Root diff --git a/tosca2heat/tosca-parser/toscaparser/tests/test_properties.py b/tosca2heat/tosca-parser/toscaparser/tests/test_properties.py index 6b95537..faa8af4 100644 --- a/tosca2heat/tosca-parser/toscaparser/tests/test_properties.py +++ b/tosca2heat/tosca-parser/toscaparser/tests/test_properties.py @@ -314,6 +314,31 @@ class PropertyTest(TestCase): num_cpus: 1 ''' + tosca_custom_def_example3 = ''' + tosca.capabilities.New: + derived_from: tosca.capabilities.Node + properties: + test_case: + type: integer + required: yes + + tosca.nodes.ComputeNew: + derived_from: tosca.nodes.Compute + capabilities: + scalable: + type: tosca.capabilities.New + ''' + + tosca_node_template_example3 = ''' + node_templates: + compute_instance: + type: tosca.nodes.ComputeNew + capabilities: + scalable: + properties: + test_case: 1 + ''' + tpl1 = self._get_nodetemplate(tosca_node_template_example1, tosca_custom_def_example1) self.assertIsNone(tpl1.validate()) @@ -322,6 +347,10 @@ class PropertyTest(TestCase): tosca_custom_def_example2) self.assertIsNone(tpl2.validate()) + tpl3 = self._get_nodetemplate(tosca_node_template_example3, + tosca_custom_def_example3) + self.assertIsNone(tpl3.validate()) + def _get_nodetemplate(self, tpl_snippet, custom_def_snippet=None): nodetemplates = yamlparser.\ diff --git a/tosca2heat/tosca-parser/toscaparser/tests/test_toscatplvalidation.py b/tosca2heat/tosca-parser/toscaparser/tests/test_toscatplvalidation.py index a8b1590..ea27bcb 100644 --- a/tosca2heat/tosca-parser/toscaparser/tests/test_toscatplvalidation.py +++ b/tosca2heat/tosca-parser/toscaparser/tests/test_toscatplvalidation.py @@ -1442,6 +1442,17 @@ heat-translator/master/translator/tests/data/custom_types/wordpress.yaml (_('The template version "tosca_xyz" is invalid. Valid versions ' 'are "%s".') % valid_versions)) + def test_import_invalid_type(self): + tosca_tpl = os.path.join( + os.path.dirname(os.path.abspath(__file__)), + "data/test_import_invalid_type.yaml") + self.assertRaises(exception.ValidationError, ToscaTemplate, tosca_tpl) + exception.ExceptionCollector.assertExceptionMessage( + exception.UnknownFieldError, + (_("Template {'invalid': 'custom_types/invalid_type.yaml'} " + 'contains unknown field "annotation_types". Refer to the ' + 'definition to verify valid values.'))) + def test_node_template_capabilities_properties(self): # validating capability property values tpl_snippet = ''' @@ -2,7 +2,7 @@ # such as verigraph [tox] minversion = 1.6 -envlist = py27,pep8 +envlist = py27,pep8,docs,docs-linkcheck skipsdist = True [testenv] @@ -24,3 +24,13 @@ whitelist_externals = commands = bash -c 'cd tosca2heat/tosca-parser; tox' +[testenv:docs] +usedevelop = False +deps = -rdocs/requirements.txt +commands = + sphinx-build -b html -n -d {envtmpdir}/doctrees ./docs/ {toxinidir}/docs/_build/html + +[testenv:docs-linkcheck] +usedevelop = False +deps = -rdocs/requirements.txt +commands = sphinx-build -b linkcheck -d {envtmpdir}/doctrees ./docs/ {toxinidir}/docs/_build/linkcheck diff --git a/verigraph/build.xml b/verigraph/build.xml index dae4678..ba576a7 100644 --- a/verigraph/build.xml +++ b/verigraph/build.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?> <!-- - Copyright (c) 2017 Politecnico di Torino and others. + Copyright (c) 2017/18 Politecnico di Torino and others. All rights reserved. This program and the accompanying materials are made available under the terms of the Apache License, Version 2.0 @@ -14,6 +14,9 @@ <property name="root.location" location="." /> <!-- The location to be used for class files --> + <property name="docker-grpc.dir" value="${root.location}/docker/gRPC" /> + <property name="docker-rest.dir" value="${root.location}/docker/REST" /> + <property name="cli.dir" value="${root.location}/VerigraphCLI" /> <property name="src.dir" location="${root.location}/src" /> <property name="gen.dir" location="${root.location}/gen-src" /> <property name="war.dir" location="${root.location}/war" /> @@ -23,6 +26,9 @@ <property name="lib.dir" location="${root.location}/lib" /> <property name="schemadir" location="${root.location}/schema" /> <property name="schemafile" value="xml_components.xsd" /> + <property name="toscaschemadir" location="${root.location}/schema/tosca" /> + <property name="toscaschemafile" value="TOSCA-v1.0.xsd" /> + <property name="toscaverigraphschemafile" value="ToscaTypes_XMLconfig.xsd" /> <property name="testfile" value="test.py" /> <property name="target" value="1.8" /> <property name="source" value="1.8" /> @@ -86,22 +92,38 @@ <delete file="${lib.dir}/z3-4.5.0-x86-win.zip" /> </target> - - <target name="-chk-bindings"> - <uptodate property="generate-bindings.notRequired" targetfile="${src.dir}/.flagfile"> - <srcfiles dir="${schemadir}" includes="${schemafile}" /> + + <target name="chk-bindings"> + <uptodate property="generate-bindings.notRequired" targetfile="${gen.dir}/.flagfile"> + <srcresources> + <fileset dir="${schemadir}" includes="${schemafile}" /> + <fileset dir="${toscaschemadir}" includes="${toscaschemafile}" /> + <fileset dir="${toscaschemadir}" includes="${toscaverigraphschemafile}" /> + </srcresources> </uptodate> </target> - - <target name="generate-bindings" unless="generate-bindings.notRequired" depends="init" description="Create the value classes"> + <target name="generate-bindings" unless="generate-bindings.notRequired" depends="init, chk-bindings" description="Create the value classes"> <exec executable="xjc" failonerror="true"> <arg line="-d ${gen.dir} -p it.polito.neo4j.jaxb ${schemadir}/${schemafile}" /> </exec> - <touch file="${src.dir}/.flagfile" /> + <exec executable="xjc" failonerror="true"> + <arg line="-d ${gen.dir} -p it.polito.tosca.jaxb ${toscaschemadir}/${toscaschemafile}" /> + </exec> + <mkdir dir="${root.location}/temp-gen" /> + <exec executable="xjc" failonerror="true"> + <arg line="-d ${root.location}/temp-gen -p it.polito.tosca.jaxb ${toscaschemadir}/${toscaverigraphschemafile}" /> + </exec> + + <copy toDir="${gen.dir}/it/polito/tosca/jaxb" overwrite="true"> + <file name="${root.location}/temp-gen/it/polito/tosca/jaxb/Configuration.java" /> + </copy> + <delete dir="${root.location}/temp-gen" /> + + <touch file="${gen.dir}/.flagfile" /> </target> - + <!-- The target for compiling the Verigraph application --> <target name="build-service" depends="init, generate-bindings, mvn-init"> <echo>Building verigraph (if needed)...</echo> @@ -166,12 +188,10 @@ </sequential> </macrodef> - <target name="war-exploded" depends="build-service"> <war-exploded /> </target> - <target name="generate-war" depends="war-exploded"> <war destfile="${gen-war.dir}/${serviceName}.war" basedir="${gen-tomcat-service.dir}"> <exclude name="protoc-dependencies/" /> @@ -181,7 +201,80 @@ </war> </target> - + <target name="docker-rest-build" depends="generate-war"> + <delete file="${docker-rest.dir}/verigraph.war" /> + + <copy file="${gen-war.dir}/verigraph.war" toDir="${docker-rest.dir}" /> + </target> + + <target name="docker-grpc-build" depends="build-service"> + <delete dir="${docker-grpc.dir}/service_lib" /> + <mkdir dir="${docker-grpc.dir}/service_lib" /> + + <copy toDir="${docker-grpc.dir}/service_lib" flatten="true" overwrite="true"> + <fileset refid="runtime.fileset" /> + </copy> + <copy file="${lib.dir}/com.microsoft.z3.jar" todir="${docker-grpc.dir}/service_lib" /> + + <delete file="${docker-grpc.dir}/server.properties" /> + <delete dir="${docker-grpc.dir}/jsonschema" /> + <copy file="${root.location}/server.properties" todir="${docker-grpc.dir}" /> + <copydir src="${root.location}/jsonschema" dest="${docker-grpc.dir}/jsonschema" /> + + <path id="jars.path"> + <fileset dir="${docker-grpc.dir}"> + <include name="service_lib/*.jar" /> + </fileset> + </path> + + <pathconvert property="jars.mf" pathsep=" "> + <path refid="jars.path" /> + <flattenmapper /> + <map from="" to="service_lib/" /> + </pathconvert> + + <delete file="${docker-grpc.dir}/service.jar"/> + <jar destfile="${docker-grpc.dir}/service.jar"> + <manifest> + <attribute name="Main-Class" value="it.polito.verigraph.grpc.server.Service"/> + <attribute name="Class-Path" value="${jars.mf}"/> + </manifest> + <fileset dir="${root.location}/build"/> + </jar> + </target> + + + <target name="build-cli-jar" depends="build-service"> + <delete dir="${cli.dir}" /> + <mkdir dir="${cli.dir}" /> + + <copy toDir="${cli.dir}/service_lib" flatten="true" overwrite="true"> + <fileset refid="runtime.fileset" /> + </copy> + <copy file="${src.dir}/it/polito/verigraph/tosca/README_CLI.txt" todir="${cli.dir}" /> + + <path id="jars.path"> + <fileset dir="${cli.dir}"> + <include name="service_lib/*.jar" /> + </fileset> + </path> + + <pathconvert property="jars.mf" pathsep=" "> + <path refid="jars.path" /> + <flattenmapper /> + <map from="" to="service_lib/" /> + </pathconvert> + + <delete file="${cli.dir}/VerigraphCLI.jar"/> + <jar destfile="${cli.dir}/VerigraphCLI.jar"> + <manifest> + <attribute name="Main-Class" value="it.polito.verigraph.tosca.ToscaCLI"/> + <attribute name="Class-Path" value="${jars.mf}"/> + </manifest> + <fileset dir="${root.location}/build"/> + </jar> + </target> + <!-- launch test python test --> <target name="run-test"> <exec dir="${test.dir}" executable="python"> @@ -191,8 +284,6 @@ </exec> </target> - - <!-- target for cleaning --> <target name="clean"> <delete dir="${build.dir}" /> @@ -200,7 +291,12 @@ <delete dir="${gen-tomcat-service.dir}" /> <delete dir="${war.dir}" /> <delete dir="${lib.dir}" /> + <delete dir="${docker-grpc.dir}/service_lib" /> + <delete dir="${docker-grpc.dir}/jsonschema" /> + <delete file="${docker-grpc.dir}/server.properties" /> + <delete file="${docker-grpc.dir}/service.jar" /> + <delete file="${docker-rest.dir}/verigraph.war" /> + <delete dir="${cli.dir}" /> </target> - </project>
\ No newline at end of file diff --git a/verigraph/gRPC-build.xml b/verigraph/gRPC-build.xml index 7ff5549..50483c8 100644 --- a/verigraph/gRPC-build.xml +++ b/verigraph/gRPC-build.xml @@ -1,7 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?> <!-- Copyright (c) 2017 Politecnico di Torino and others. - All rights reserved. This program and the accompanying materials are made available under the terms of the Apache License, Version 2.0 which accompanies this distribution, and is available at @@ -31,6 +30,8 @@ <property name="test2.class" value="it.polito.verigraph.grpc.test.GrpcTest" /> <property name="test3.class" value="it.polito.verigraph.grpc.test.MultiThreadTest" /> <property name="test4.class" value="it.polito.verigraph.grpc.test.ReachabilityTest" /> + <!-- Tosca grpc test class --> + <property name="testToscaGrpc.class" value="it.polito.verigraph.grpc.tosca.test.GrpcToscaTest" /> <!-- The name to be given to the final zip --> <property name="sol.zip" value="grpc.zip" /> <!-- Java compiler settings --> @@ -43,7 +44,7 @@ <path id="test.classpath"> <pathelement path="${build.dir}" /> <fileset dir="${grpc.location}/lib"> - <include name="com.microsoft.z3.jar" /> + <include name="com.microsoft.z3.jar" /> </fileset> <fileset refid="mvn-dependencies" /> </path> @@ -65,7 +66,7 @@ </artifact:dependencies>--> <path id="build.classpath"> - <fileset refid="mvn-dependencies" /> + <fileset refid="mvn-dependencies" /> </path> <!-- target name="init"> @@ -77,7 +78,7 @@ <!--target name="gRPC-build" depends="init" description="Build the sources"--> <target name="gRPC-build" description="Build the sources"> <echo>Building gRPC (if needed)...</echo> - <javac + <javac debug="${debug}" debuglevel="${debuglevel}" source="${source}" @@ -85,18 +86,18 @@ destdir="${build.dir}" classpathref="build.classpath" includeantruntime="false"> - <src path="${generated.dir}" /> - <src path="${src.dir}" /> - <src path="${grpc.location}/gen-src"/> - <compilerarg value="-Xlint:unchecked"/> - <classpath> - <pathelement path="${grpc.location}/lib/com.microsoft.z3.jar"/> - </classpath> - <include name="$it/polito/**/**/*.java"/> - <!-- classpath> + <src path="${generated.dir}" /> + <src path="${src.dir}" /> + <src path="${grpc.location}/gen-src"/> + <compilerarg value="-Xlint:unchecked"/> + <classpath> + <pathelement path="${grpc.location}/lib/com.microsoft.z3.jar"/> + </classpath> + <include name="$it/polito/**/**/*.java"/> + <!-- classpath> <pathelement path="${other_lib.dir}/qjutils.jar"/> </classpath--> - </javac> + </javac> <echo>Done.</echo> </target> @@ -104,20 +105,21 @@ <!-- The target for running the gRPC application --> <target name="gRPC-run" depends="gRPC-build" description="Run gRPC"> <parallel> - <sequential> - <java classname="it.polito.verigraph.grpc.Service" failonerror="true" classpathref="build.classpath" fork="yes"> - <classpath> - <pathelement path="${build.dir}"/> - </classpath> - </java> - </sequential> - <sequential> - <sleep milliseconds="500"/> - <java classname="it.polito.verigraph.grpc.Client" failonerror="true" classpathref="build.classpath" fork="yes"> - <classpath> - <pathelement path="${build.dir}"/> - </classpath> - </java> + <sequential> + <java classname="it.polito.verigraph.grpc.Service" failonerror="true" classpathref="build.classpath" fork="yes"> + <classpath> + <pathelement path="${build.dir}"/> + <path refid="test.classpath" /> + </classpath> + </java> + </sequential> + <sequential> + <sleep milliseconds="500"/> + <java classname="it.polito.verigraph.grpc.Client" failonerror="true" classpathref="build.classpath" fork="yes"> + <classpath> + <pathelement path="${build.dir}"/> + </classpath> + </java> </sequential> </parallel> </target> @@ -136,6 +138,7 @@ <java classname="it.polito.verigraph.grpc.server.Service" failonerror="true" classpathref="build.classpath" fork="yes"> <classpath> <pathelement path="${build.dir}"/> + <path refid="test.classpath" /> </classpath> </java> </target> @@ -151,6 +154,19 @@ </antcall> </target> + <!-- Run Tosca Grpc Tests --> + <target name="gRPC-tosca-run-tests" description="Run tests for Tosca implementation of gRPC"> + <echo>Running grpc tests...</echo> + <junit printsummary="yes" dir="." fork="yes" haltonfailure="no" showoutput="yes" filtertrace="true" timeout="120000"> + <jvmarg value="-Djava.awt.headless=true" /> + <formatter type="brief" usefile="false" /> + <test haltonfailure="no" failureproperty="test_failed" name="${testToscaGrpc.class}" /> + <classpath> + <path refid="test.classpath" /> + </classpath> + </junit> + <fail if="test_failed" message="*** JUnit tests for gRPC Tosca completed: some Tests FAILED ***" /> + </target> <!-- Target runFuncTest.real --> <target name="runFuncTest.real" depends="gRPC-build"> @@ -213,4 +229,4 @@ <!-- target name="clean"> <delete dir="${build.dir}" /> </target--> -</project>
\ No newline at end of file +</project> diff --git a/verigraph/pom.xml b/verigraph/pom.xml index cfa21e9..9684667 100755 --- a/verigraph/pom.xml +++ b/verigraph/pom.xml @@ -37,8 +37,8 @@ <version>3.0</version>
<inherited>true</inherited>
<configuration>
- <source>1.7</source>
- <target>1.7</target>
+ <source>1.8</source>
+ <target>1.8</target>
</configuration>
</plugin>
<plugin>
@@ -218,6 +218,16 @@ <artifactId>slf4j-log4j12</artifactId>
<version>1.6.4</version>
</dependency>
+ <dependency>
+ <groupId>com.fasterxml.jackson.dataformat</groupId>
+ <artifactId>jackson-dataformat-yaml</artifactId>
+ <version>2.9.2</version>
+ </dependency>
+ <!-- Trying to make jaxb work -->
+ <dependency>
+ <groupId>org.eclipse.persistence</groupId>
+ <artifactId>org.eclipse.persistence.core</artifactId>
+ <version>2.6.0</version>
+ </dependency>
</dependencies>
-
</project>
\ No newline at end of file diff --git a/verigraph/schema/README.rst b/verigraph/schema/README.rst new file mode 100644 index 0000000..c3e7a22 --- /dev/null +++ b/verigraph/schema/README.rst @@ -0,0 +1,4 @@ +.. This work is licensed under a Creative Commons Attribution 4.0 International License. +.. http://creativecommons.org/licenses/by/4.0 +The XML Schema files in this folder are used by VeriGraph to +automatically generate Java XML Bindings (JAXB) diff --git a/verigraph/schema/tosca/TOSCA-v1.0.xsd b/verigraph/schema/tosca/TOSCA-v1.0.xsd new file mode 100644 index 0000000..ebfcaa6 --- /dev/null +++ b/verigraph/schema/tosca/TOSCA-v1.0.xsd @@ -0,0 +1,790 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Topology and Orchestration Specification for Cloud Applications Version 1.0 + OASIS Standard + 25 November 2013 + Copyright (c) OASIS Open 2013. All rights reserved. + Source: http://docs.oasis-open.org/tosca/TOSCA/v1.0/os/schemas/ +--> +<xs:schema targetNamespace="http://docs.oasis-open.org/tosca/ns/2011/12" elementFormDefault="qualified" attributeFormDefault="unqualified" xmlns="http://docs.oasis-open.org/tosca/ns/2011/12" xmlns:xs="http://www.w3.org/2001/XMLSchema"> + <xs:import namespace="http://www.w3.org/XML/1998/namespace" schemaLocation="http://www.w3.org/2001/xml.xsd"/> + <xs:element name="documentation" type="tDocumentation"/> + <xs:complexType name="tDocumentation" mixed="true"> + <xs:sequence> + <xs:any processContents="lax" minOccurs="0" maxOccurs="unbounded"/> + </xs:sequence> + <xs:attribute name="source" type="xs:anyURI"/> + <xs:attribute ref="xml:lang"/> + </xs:complexType> + <xs:complexType name="tExtensibleElements"> + <xs:sequence> + <xs:element ref="documentation" minOccurs="0" maxOccurs="unbounded"/> + <xs:any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded"/> + </xs:sequence> + <xs:anyAttribute namespace="##other" processContents="lax"/> + </xs:complexType> + <xs:complexType name="tImport"> + <xs:complexContent> + <xs:extension base="tExtensibleElements"> + <xs:attribute name="namespace" type="xs:anyURI"/> + <xs:attribute name="location" type="xs:anyURI"/> + <xs:attribute name="importType" type="importedURI" use="required"/> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:element name="Definitions"> + <xs:complexType> + <xs:complexContent> + <xs:extension base="tDefinitions"/> + </xs:complexContent> + </xs:complexType> + </xs:element> + <xs:complexType name="tDefinitions"> + <xs:complexContent> + <xs:extension base="tExtensibleElements"> + <xs:sequence> + <xs:element name="Extensions" minOccurs="0"> + <xs:complexType> + <xs:sequence> + <xs:element name="Extension" type="tExtension" maxOccurs="unbounded"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="Import" type="tImport" minOccurs="0" maxOccurs="unbounded"/> + <xs:element name="Types" minOccurs="0"> + <xs:complexType> + <xs:sequence> + <xs:any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:choice maxOccurs="unbounded"> + <xs:element name="ServiceTemplate" type="tServiceTemplate"/> + <xs:element name="NodeType" type="tNodeType"/> + <xs:element name="NodeTypeImplementation" type="tNodeTypeImplementation"/> + <xs:element name="RelationshipType" type="tRelationshipType"/> + <xs:element name="RelationshipTypeImplementation" type="tRelationshipTypeImplementation"/> + <xs:element name="RequirementType" type="tRequirementType"/> + <xs:element name="CapabilityType" type="tCapabilityType"/> + <xs:element name="ArtifactType" type="tArtifactType"/> + <xs:element name="ArtifactTemplate" type="tArtifactTemplate"/> + <xs:element name="PolicyType" type="tPolicyType"/> + <xs:element name="PolicyTemplate" type="tPolicyTemplate"/> + </xs:choice> + </xs:sequence> + <xs:attribute name="id" type="xs:ID" use="required"/> + <xs:attribute name="name" type="xs:string" use="optional"/> + <xs:attribute name="targetNamespace" type="xs:anyURI" use="required"/> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="tServiceTemplate"> + <xs:complexContent> + <xs:extension base="tExtensibleElements"> + <xs:sequence> + <xs:element name="Tags" type="tTags" minOccurs="0"/> + <xs:element name="BoundaryDefinitions" type="tBoundaryDefinitions" minOccurs="0"/> + <xs:element name="TopologyTemplate" type="tTopologyTemplate"/> + <xs:element name="Plans" type="tPlans" minOccurs="0"/> + </xs:sequence> + <xs:attribute name="id" type="xs:ID" use="required"/> + <xs:attribute name="name" type="xs:string" use="optional"/> + <xs:attribute name="targetNamespace" type="xs:anyURI"/> + <xs:attribute name="substitutableNodeType" type="xs:QName" use="optional"/> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="tTags"> + <xs:sequence> + <xs:element name="Tag" type="tTag" maxOccurs="unbounded"/> + </xs:sequence> + </xs:complexType> + <xs:complexType name="tTag"> + <xs:attribute name="name" type="xs:string" use="required"/> + <xs:attribute name="value" type="xs:string" use="required"/> + </xs:complexType> + <xs:complexType name="tBoundaryDefinitions"> + <xs:sequence> + <xs:element name="Properties" minOccurs="0"> + <xs:complexType> + <xs:sequence> + <xs:any namespace="##other"/> + <xs:element name="PropertyMappings" minOccurs="0"> + <xs:complexType> + <xs:sequence> + <xs:element name="PropertyMapping" type="tPropertyMapping" maxOccurs="unbounded"/> + </xs:sequence> + </xs:complexType> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="PropertyConstraints" minOccurs="0"> + <xs:complexType> + <xs:sequence> + <xs:element name="PropertyConstraint" type="tPropertyConstraint" maxOccurs="unbounded"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="Requirements" minOccurs="0"> + <xs:complexType> + <xs:sequence> + <xs:element name="Requirement" type="tRequirementRef" maxOccurs="unbounded"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="Capabilities" minOccurs="0"> + <xs:complexType> + <xs:sequence> + <xs:element name="Capability" type="tCapabilityRef" maxOccurs="unbounded"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="Policies" minOccurs="0"> + <xs:complexType> + <xs:sequence> + <xs:element name="Policy" type="tPolicy" maxOccurs="unbounded"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="Interfaces" minOccurs="0"> + <xs:complexType> + <xs:sequence> + <xs:element name="Interface" type="tExportedInterface" maxOccurs="unbounded"/> + </xs:sequence> + </xs:complexType> + </xs:element> + </xs:sequence> + </xs:complexType> + <xs:complexType name="tPropertyMapping"> + <xs:attribute name="serviceTemplatePropertyRef" type="xs:string" use="required"/> + <xs:attribute name="targetObjectRef" type="xs:IDREF" use="required"/> + <xs:attribute name="targetPropertyRef" type="xs:string" use="required"/> + </xs:complexType> + <xs:complexType name="tRequirementRef"> + <xs:attribute name="name" type="xs:string" use="optional"/> + <xs:attribute name="ref" type="xs:IDREF" use="required"/> + </xs:complexType> + <xs:complexType name="tCapabilityRef"> + <xs:attribute name="name" type="xs:string" use="optional"/> + <xs:attribute name="ref" type="xs:IDREF" use="required"/> + </xs:complexType> + <xs:complexType name="tEntityType" abstract="true"> + <xs:complexContent> + <xs:extension base="tExtensibleElements"> + <xs:sequence> + <xs:element name="Tags" type="tTags" minOccurs="0"/> + <xs:element name="DerivedFrom" minOccurs="0"> + <xs:complexType> + <xs:attribute name="typeRef" type="xs:QName" use="required"/> + </xs:complexType> + </xs:element> + <xs:element name="PropertiesDefinition" minOccurs="0"> + <xs:complexType> + <xs:attribute name="element" type="xs:QName"/> + <xs:attribute name="type" type="xs:QName"/> + </xs:complexType> + </xs:element> + </xs:sequence> + <xs:attribute name="name" type="xs:NCName" use="required"/> + <xs:attribute name="abstract" type="tBoolean" default="no"/> + <xs:attribute name="final" type="tBoolean" default="no"/> + <xs:attribute name="targetNamespace" type="xs:anyURI" use="optional"/> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="tEntityTemplate" abstract="true"> + <xs:complexContent> + <xs:extension base="tExtensibleElements"> + <xs:sequence> + <xs:element name="Properties" minOccurs="0"> + <xs:complexType> + <xs:sequence> + <xs:any namespace="##other" processContents="lax"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="PropertyConstraints" minOccurs="0"> + <xs:complexType> + <xs:sequence> + <xs:element name="PropertyConstraint" type="tPropertyConstraint" maxOccurs="unbounded"/> + </xs:sequence> + </xs:complexType> + </xs:element> + </xs:sequence> + <xs:attribute name="id" type="xs:ID" use="required"/> + <xs:attribute name="type" type="xs:QName" use="required"/> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="tNodeTemplate"> + <xs:complexContent> + <xs:extension base="tEntityTemplate"> + <xs:sequence> + <xs:element name="Requirements" minOccurs="0"> + <xs:complexType> + <xs:sequence> + <xs:element name="Requirement" type="tRequirement" maxOccurs="unbounded"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="Capabilities" minOccurs="0"> + <xs:complexType> + <xs:sequence> + <xs:element name="Capability" type="tCapability" maxOccurs="unbounded"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="Policies" minOccurs="0"> + <xs:complexType> + <xs:sequence> + <xs:element name="Policy" type="tPolicy" maxOccurs="unbounded"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="DeploymentArtifacts" type="tDeploymentArtifacts" minOccurs="0"/> + </xs:sequence> + <xs:attribute name="name" type="xs:string" use="optional"/> + <xs:attribute name="minInstances" type="xs:int" use="optional" default="1"/> + <xs:attribute name="maxInstances" use="optional" default="1"> + <xs:simpleType> + <xs:union> + <xs:simpleType> + <xs:restriction base="xs:nonNegativeInteger"> + <xs:pattern value="([1-9]+[0-9]*)"/> + </xs:restriction> + </xs:simpleType> + <xs:simpleType> + <xs:restriction base="xs:string"> + <xs:enumeration value="unbounded"/> + </xs:restriction> + </xs:simpleType> + </xs:union> + </xs:simpleType> + </xs:attribute> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="tTopologyTemplate"> + <xs:complexContent> + <xs:extension base="tExtensibleElements"> + <xs:choice maxOccurs="unbounded"> + <xs:element name="NodeTemplate" type="tNodeTemplate"/> + <xs:element name="RelationshipTemplate" type="tRelationshipTemplate"/> + </xs:choice> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="tRelationshipType"> + <xs:complexContent> + <xs:extension base="tEntityType"> + <xs:sequence> + <xs:element name="InstanceStates" type="tTopologyElementInstanceStates" minOccurs="0"/> + <xs:element name="SourceInterfaces" minOccurs="0"> + <xs:complexType> + <xs:sequence> + <xs:element name="Interface" type="tInterface" maxOccurs="unbounded"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="TargetInterfaces" minOccurs="0"> + <xs:complexType> + <xs:sequence> + <xs:element name="Interface" type="tInterface" maxOccurs="unbounded"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="ValidSource" minOccurs="0"> + <xs:complexType> + <xs:attribute name="typeRef" type="xs:QName" use="required"/> + </xs:complexType> + </xs:element> + <xs:element name="ValidTarget" minOccurs="0"> + <xs:complexType> + <xs:attribute name="typeRef" type="xs:QName" use="required"/> + </xs:complexType> + </xs:element> + </xs:sequence> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="tRelationshipTypeImplementation"> + <xs:complexContent> + <xs:extension base="tExtensibleElements"> + <xs:sequence> + <xs:element name="Tags" type="tTags" minOccurs="0"/> + <xs:element name="DerivedFrom" minOccurs="0"> + <xs:complexType> + <xs:attribute name="relationshipTypeImplementationRef" type="xs:QName" use="required"/> + </xs:complexType> + </xs:element> + <xs:element name="RequiredContainerFeatures" type="tRequiredContainerFeatures" minOccurs="0"/> + <xs:element name="ImplementationArtifacts" type="tImplementationArtifacts" minOccurs="0"/> + </xs:sequence> + <xs:attribute name="name" type="xs:NCName" use="required"/> + <xs:attribute name="targetNamespace" type="xs:anyURI" use="optional"/> + <xs:attribute name="relationshipType" type="xs:QName" use="required"/> + <xs:attribute name="abstract" type="tBoolean" use="optional" default="no"/> + <xs:attribute name="final" type="tBoolean" use="optional" default="no"/> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="tRelationshipTemplate"> + <xs:complexContent> + <xs:extension base="tEntityTemplate"> + <xs:sequence> + <xs:element name="SourceElement"> + <xs:complexType> + <xs:attribute name="ref" type="xs:IDREF" use="required"/> + </xs:complexType> + </xs:element> + <xs:element name="TargetElement"> + <xs:complexType> + <xs:attribute name="ref" type="xs:IDREF" use="required"/> + </xs:complexType> + </xs:element> + <xs:element name="RelationshipConstraints" minOccurs="0"> + <xs:complexType> + <xs:sequence> + <xs:element name="RelationshipConstraint" maxOccurs="unbounded"> + <xs:complexType> + <xs:sequence> + <xs:any namespace="##other" processContents="lax" minOccurs="0"/> + </xs:sequence> + <xs:attribute name="constraintType" type="xs:anyURI" use="required"/> + </xs:complexType> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> + </xs:sequence> + <xs:attribute name="name" type="xs:string" use="optional"/> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="tNodeType"> + <xs:complexContent> + <xs:extension base="tEntityType"> + <xs:sequence> + <xs:element name="RequirementDefinitions" minOccurs="0"> + <xs:complexType> + <xs:sequence> + <xs:element name="RequirementDefinition" type="tRequirementDefinition" maxOccurs="unbounded"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="CapabilityDefinitions" minOccurs="0"> + <xs:complexType> + <xs:sequence> + <xs:element name="CapabilityDefinition" type="tCapabilityDefinition" maxOccurs="unbounded"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="InstanceStates" type="tTopologyElementInstanceStates" minOccurs="0"/> + <xs:element name="Interfaces" minOccurs="0"> + <xs:complexType> + <xs:sequence> + <xs:element name="Interface" type="tInterface" maxOccurs="unbounded"/> + </xs:sequence> + </xs:complexType> + </xs:element> + </xs:sequence> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="tNodeTypeImplementation"> + <xs:complexContent> + <xs:extension base="tExtensibleElements"> + <xs:sequence> + <xs:element name="Tags" type="tTags" minOccurs="0"/> + <xs:element name="DerivedFrom" minOccurs="0"> + <xs:complexType> + <xs:attribute name="nodeTypeImplementationRef" type="xs:QName" use="required"/> + </xs:complexType> + </xs:element> + <xs:element name="RequiredContainerFeatures" type="tRequiredContainerFeatures" minOccurs="0"/> + <xs:element name="ImplementationArtifacts" type="tImplementationArtifacts" minOccurs="0"/> + <xs:element name="DeploymentArtifacts" type="tDeploymentArtifacts" minOccurs="0"/> + </xs:sequence> + <xs:attribute name="name" type="xs:NCName" use="required"/> + <xs:attribute name="targetNamespace" type="xs:anyURI" use="optional"/> + <xs:attribute name="nodeType" type="xs:QName" use="required"/> + <xs:attribute name="abstract" type="tBoolean" use="optional" default="no"/> + <xs:attribute name="final" type="tBoolean" use="optional" default="no"/> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="tRequirementType"> + <xs:complexContent> + <xs:extension base="tEntityType"> + <xs:attribute name="requiredCapabilityType" type="xs:QName" use="optional"/> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="tRequirementDefinition"> + <xs:complexContent> + <xs:extension base="tExtensibleElements"> + <xs:sequence> + <xs:element name="Constraints" minOccurs="0"> + <xs:complexType> + <xs:sequence> + <xs:element name="Constraint" type="tConstraint" maxOccurs="unbounded"/> + </xs:sequence> + </xs:complexType> + </xs:element> + </xs:sequence> + <xs:attribute name="name" type="xs:string" use="required"/> + <xs:attribute name="requirementType" type="xs:QName" use="required"/> + <xs:attribute name="lowerBound" type="xs:int" use="optional" default="1"/> + <xs:attribute name="upperBound" use="optional" default="1"> + <xs:simpleType> + <xs:union> + <xs:simpleType> + <xs:restriction base="xs:nonNegativeInteger"> + <xs:pattern value="([1-9]+[0-9]*)"/> + </xs:restriction> + </xs:simpleType> + <xs:simpleType> + <xs:restriction base="xs:string"> + <xs:enumeration value="unbounded"/> + </xs:restriction> + </xs:simpleType> + </xs:union> + </xs:simpleType> + </xs:attribute> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="tRequirement"> + <xs:complexContent> + <xs:extension base="tEntityTemplate"> + <xs:attribute name="name" type="xs:string" use="required"/> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="tCapabilityType"> + <xs:complexContent> + <xs:extension base="tEntityType"/> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="tCapabilityDefinition"> + <xs:complexContent> + <xs:extension base="tExtensibleElements"> + <xs:sequence> + <xs:element name="Constraints" minOccurs="0"> + <xs:complexType> + <xs:sequence> + <xs:element name="Constraint" type="tConstraint" maxOccurs="unbounded"/> + </xs:sequence> + </xs:complexType> + </xs:element> + </xs:sequence> + <xs:attribute name="name" type="xs:string" use="required"/> + <xs:attribute name="capabilityType" type="xs:QName" use="required"/> + <xs:attribute name="lowerBound" type="xs:int" use="optional" default="1"/> + <xs:attribute name="upperBound" use="optional" default="1"> + <xs:simpleType> + <xs:union> + <xs:simpleType> + <xs:restriction base="xs:nonNegativeInteger"> + <xs:pattern value="([1-9]+[0-9]*)"/> + </xs:restriction> + </xs:simpleType> + <xs:simpleType> + <xs:restriction base="xs:string"> + <xs:enumeration value="unbounded"/> + </xs:restriction> + </xs:simpleType> + </xs:union> + </xs:simpleType> + </xs:attribute> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="tCapability"> + <xs:complexContent> + <xs:extension base="tEntityTemplate"> + <xs:attribute name="name" type="xs:string" use="required"/> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="tArtifactType"> + <xs:complexContent> + <xs:extension base="tEntityType"/> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="tArtifactTemplate"> + <xs:complexContent> + <xs:extension base="tEntityTemplate"> + <xs:sequence> + <xs:element name="ArtifactReferences" minOccurs="0"> + <xs:complexType> + <xs:sequence> + <xs:element name="ArtifactReference" type="tArtifactReference" maxOccurs="unbounded"/> + </xs:sequence> + </xs:complexType> + </xs:element> + </xs:sequence> + <xs:attribute name="name" type="xs:string" use="optional"/> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="tDeploymentArtifacts"> + <xs:sequence> + <xs:element name="DeploymentArtifact" type="tDeploymentArtifact" maxOccurs="unbounded"/> + </xs:sequence> + </xs:complexType> + <xs:complexType name="tDeploymentArtifact"> + <xs:complexContent> + <xs:extension base="tExtensibleElements"> + <xs:attribute name="name" type="xs:string" use="required"/> + <xs:attribute name="artifactType" type="xs:QName" use="required"/> + <xs:attribute name="artifactRef" type="xs:QName" use="optional"/> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="tImplementationArtifacts"> + <xs:sequence> + <xs:element name="ImplementationArtifact" maxOccurs="unbounded"> + <xs:complexType> + <xs:complexContent> + <xs:extension base="tImplementationArtifact"/> + </xs:complexContent> + </xs:complexType> + </xs:element> + </xs:sequence> + </xs:complexType> + <xs:complexType name="tImplementationArtifact"> + <xs:complexContent> + <xs:extension base="tExtensibleElements"> + <xs:attribute name="interfaceName" type="xs:anyURI" use="optional"/> + <xs:attribute name="operationName" type="xs:NCName" use="optional"/> + <xs:attribute name="artifactType" type="xs:QName" use="required"/> + <xs:attribute name="artifactRef" type="xs:QName" use="optional"/> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="tPlans"> + <xs:sequence> + <xs:element name="Plan" type="tPlan" maxOccurs="unbounded"/> + </xs:sequence> + <xs:attribute name="targetNamespace" type="xs:anyURI" use="optional"/> + </xs:complexType> + <xs:complexType name="tPlan"> + <xs:complexContent> + <xs:extension base="tExtensibleElements"> + <xs:sequence> + <xs:element name="Precondition" type="tCondition" minOccurs="0"/> + <xs:element name="InputParameters" minOccurs="0"> + <xs:complexType> + <xs:sequence> + <xs:element name="InputParameter" type="tParameter" maxOccurs="unbounded"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="OutputParameters" minOccurs="0"> + <xs:complexType> + <xs:sequence> + <xs:element name="OutputParameter" type="tParameter" maxOccurs="unbounded"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:choice> + <xs:element name="PlanModel"> + <xs:complexType> + <xs:sequence> + <xs:any namespace="##other" processContents="lax"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="PlanModelReference"> + <xs:complexType> + <xs:attribute name="reference" type="xs:anyURI" use="required"/> + </xs:complexType> + </xs:element> + </xs:choice> + </xs:sequence> + <xs:attribute name="id" type="xs:ID" use="required"/> + <xs:attribute name="name" type="xs:string" use="optional"/> + <xs:attribute name="planType" type="xs:anyURI" use="required"/> + <xs:attribute name="planLanguage" type="xs:anyURI" use="required"/> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="tPolicyType"> + <xs:complexContent> + <xs:extension base="tEntityType"> + <xs:sequence> + <xs:element name="AppliesTo" type="tAppliesTo" minOccurs="0"/> + </xs:sequence> + <xs:attribute name="policyLanguage" type="xs:anyURI" use="optional"/> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="tPolicyTemplate"> + <xs:complexContent> + <xs:extension base="tEntityTemplate"> + <xs:attribute name="name" type="xs:string" use="optional"/> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="tAppliesTo"> + <xs:sequence> + <xs:element name="NodeTypeReference" maxOccurs="unbounded"> + <xs:complexType> + <xs:attribute name="typeRef" type="xs:QName" use="required"/> + </xs:complexType> + </xs:element> + </xs:sequence> + </xs:complexType> + <xs:complexType name="tPolicy"> + <xs:complexContent> + <xs:extension base="tExtensibleElements"> + <xs:attribute name="name" type="xs:string" use="optional"/> + <xs:attribute name="policyType" type="xs:QName" use="required"/> + <xs:attribute name="policyRef" type="xs:QName" use="optional"/> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="tConstraint"> + <xs:sequence> + <xs:any namespace="##other" processContents="lax"/> + </xs:sequence> + <xs:attribute name="constraintType" type="xs:anyURI" use="required"/> + </xs:complexType> + <xs:complexType name="tPropertyConstraint"> + <xs:complexContent> + <xs:extension base="tConstraint"> + <xs:attribute name="property" type="xs:string" use="required"/> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="tExtensions"> + <xs:complexContent> + <xs:extension base="tExtensibleElements"> + <xs:sequence> + <xs:element name="Extension" type="tExtension" maxOccurs="unbounded"/> + </xs:sequence> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="tExtension"> + <xs:complexContent> + <xs:extension base="tExtensibleElements"> + <xs:attribute name="namespace" type="xs:anyURI" use="required"/> + <xs:attribute name="mustUnderstand" type="tBoolean" use="optional" default="yes"/> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="tParameter"> + <xs:attribute name="name" type="xs:string" use="required"/> + <xs:attribute name="type" type="xs:string" use="required"/> + <xs:attribute name="required" type="tBoolean" use="optional" default="yes"/> + </xs:complexType> + <xs:complexType name="tInterface"> + <xs:sequence> + <xs:element name="Operation" type="tOperation" maxOccurs="unbounded"/> + </xs:sequence> + <xs:attribute name="name" type="xs:anyURI" use="required"/> + </xs:complexType> + <xs:complexType name="tExportedInterface"> + <xs:sequence> + <xs:element name="Operation" type="tExportedOperation" maxOccurs="unbounded"/> + </xs:sequence> + <xs:attribute name="name" type="xs:anyURI" use="required"/> + </xs:complexType> + <xs:complexType name="tOperation"> + <xs:complexContent> + <xs:extension base="tExtensibleElements"> + <xs:sequence> + <xs:element name="InputParameters" minOccurs="0"> + <xs:complexType> + <xs:sequence> + <xs:element name="InputParameter" type="tParameter" maxOccurs="unbounded"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="OutputParameters" minOccurs="0"> + <xs:complexType> + <xs:sequence> + <xs:element name="OutputParameter" type="tParameter" maxOccurs="unbounded"/> + </xs:sequence> + </xs:complexType> + </xs:element> + </xs:sequence> + <xs:attribute name="name" type="xs:NCName" use="required"/> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="tExportedOperation"> + <xs:choice> + <xs:element name="NodeOperation"> + <xs:complexType> + <xs:attribute name="nodeRef" type="xs:IDREF" use="required"/> + <xs:attribute name="interfaceName" type="xs:anyURI" use="required"/> + <xs:attribute name="operationName" type="xs:NCName" use="required"/> + </xs:complexType> + </xs:element> + <xs:element name="RelationshipOperation"> + <xs:complexType> + <xs:attribute name="relationshipRef" type="xs:IDREF" use="required"/> + <xs:attribute name="interfaceName" type="xs:anyURI" use="required"/> + <xs:attribute name="operationName" type="xs:NCName" use="required"/> + </xs:complexType> + </xs:element> + <xs:element name="Plan"> + <xs:complexType> + <xs:attribute name="planRef" type="xs:IDREF" use="required"/> + </xs:complexType> + </xs:element> + </xs:choice> + <xs:attribute name="name" type="xs:NCName" use="required"/> + </xs:complexType> + <xs:complexType name="tCondition"> + <xs:sequence> + <xs:any processContents="lax" minOccurs="0" maxOccurs="unbounded"/> + </xs:sequence> + <xs:attribute name="expressionLanguage" type="xs:anyURI" use="required"/> + </xs:complexType> + <xs:complexType name="tTopologyElementInstanceStates"> + <xs:sequence> + <xs:element name="InstanceState" maxOccurs="unbounded"> + <xs:complexType> + <xs:attribute name="state" type="xs:anyURI" use="required"/> + </xs:complexType> + </xs:element> + </xs:sequence> + </xs:complexType> + <xs:complexType name="tArtifactReference"> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:element name="Include"> + <xs:complexType> + <xs:attribute name="pattern" type="xs:string" use="required"/> + </xs:complexType> + </xs:element> + <xs:element name="Exclude"> + <xs:complexType> + <xs:attribute name="pattern" type="xs:string" use="required"/> + </xs:complexType> + </xs:element> + </xs:choice> + <xs:attribute name="reference" type="xs:anyURI" use="required"/> + </xs:complexType> + <xs:complexType name="tRequiredContainerFeatures"> + <xs:sequence> + <xs:element name="RequiredContainerFeature" type="tRequiredContainerFeature" maxOccurs="unbounded"/> + </xs:sequence> + </xs:complexType> + <xs:complexType name="tRequiredContainerFeature"> + <xs:attribute name="feature" type="xs:anyURI" use="required"/> + </xs:complexType> + <xs:simpleType name="tBoolean"> + <xs:restriction base="xs:string"> + <xs:enumeration value="yes"/> + <xs:enumeration value="no"/> + </xs:restriction> + </xs:simpleType> + <xs:simpleType name="importedURI"> + <xs:restriction base="xs:anyURI"/> + </xs:simpleType> +</xs:schema> diff --git a/verigraph/schema/tosca/ToscaTypes_XMLconfig.xsd b/verigraph/schema/tosca/ToscaTypes_XMLconfig.xsd new file mode 100644 index 0000000..98751b4 --- /dev/null +++ b/verigraph/schema/tosca/ToscaTypes_XMLconfig.xsd @@ -0,0 +1,280 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (c) 2018 Politecnico di Torino and others. + + All rights reserved. This program and the accompanying materials + are made available under the terms of the Apache License, Version 2.0 + which accompanies this distribution, and is available at + http://www.apache.org/licenses/LICENSE-2.0 +--> + + +<xsd:schema xmlns="http://docs.oasis-open.org/tosca/ns/2011/12/ToscaVerigraphDefinition" + xmlns:xsd="http://www.w3.org/2001/XMLSchema" + targetNamespace="http://docs.oasis-open.org/tosca/ns/2011/12/ToscaVerigraphDefinition"> + + <!-- Generic Configuration type, contains a single configuration element --> + <xsd:element name="Configuration"> + <xsd:complexType> + <xsd:choice> + <xsd:element name="antispamConfiguration"> + <xsd:complexType> + <xsd:sequence minOccurs="1" maxOccurs="unbounded"> + <xsd:element name="source" type="xsd:string" /> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + <xsd:element name="cacheConfiguration"> + <xsd:complexType> + <xsd:sequence minOccurs="1" maxOccurs="unbounded"> + <xsd:element name="resource" type="xsd:string" /> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + <xsd:element name="dpiConfiguration"> + <xsd:complexType> + <xsd:sequence minOccurs="1" maxOccurs="unbounded"> + <xsd:element name="notAllowed" type="xsd:string" /> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + <xsd:element name="endhostConfiguration"> + <xsd:complexType> + <xsd:attribute name="body" type="xsd:string" /> + <xsd:attribute name="sequence" type="xsd:integer" /> + <xsd:attribute name="protocol"> + <xsd:simpleType> + <xsd:restriction base="xsd:string"> + <xsd:enumeration value="HTTP_REQUEST" /> + <xsd:enumeration value="HTTP_RESPONSE" /> + <xsd:enumeration value="POP3_REQUEST" /> + <xsd:enumeration value="POP3_RESPONSE" /> + </xsd:restriction> + </xsd:simpleType> + </xsd:attribute> + <xsd:attribute name="email_from" type="xsd:string" /> + <xsd:attribute name="url" type="xsd:string" /> + <xsd:attribute name="options" type="xsd:string" /> + <xsd:attribute name="destination" type="xsd:string" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="endpointConfiguration"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="name" type="xsd:string" nillable="true" /> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + <xsd:element name="fieldmodifierConfiguration"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="name" type="xsd:string" nillable="true" /> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + <xsd:element name="firewallConfiguration"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="elements" maxOccurs="unbounded"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="source" type="xsd:string" /> + <xsd:element name="destination" type="xsd:string" /> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + <xsd:element name="mailclientConfiguration"> + <xsd:complexType> + <xsd:attribute name="mailserver" type="xsd:string" + use="required" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="mailserverConfiguration"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="name" type="xsd:string" nillable="true" /> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + <xsd:element name="natConfiguration"> + <xsd:complexType> + <xsd:sequence minOccurs="1" maxOccurs="unbounded"> + <xsd:element name="source" type="xsd:string" /> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + <xsd:element name="vpnaccessConfiguration"> + <xsd:complexType> + <xsd:attribute name="vpnexit" type="xsd:string" use="required" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="vpnexitConfiguration"> + <xsd:complexType> + <xsd:attribute name="vpnaccess" type="xsd:string" + use="required" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="webclientConfiguration"> + <xsd:complexType> + <xsd:attribute name="nameWebServer" type="xsd:string" + use="required" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="webserverConfiguration"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="name" type="xsd:string" nillable="true" /> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + </xsd:choice> + <xsd:attribute name="confID" type="xsd:string" /> + <xsd:attribute name="confDescr" type="xsd:string" /> + </xsd:complexType> + </xsd:element> + + + <!-- <xsd:element name="firewallConfiguration"> + <xsd:complexType > + <xsd:sequence> + <xsd:element ref="elements" maxOccurs="unbounded" /> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + <xsd:element name="elements"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="source" type="xsd:string" /> + <xsd:element name="destination" type="xsd:string" /> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + <xsd:element name="endhostConfiguration"> + <xsd:complexType> + <xsd:attribute name="body" type="xsd:string" /> + <xsd:attribute name="sequence" type="xsd:integer" /> + <xsd:attribute name="protocol" type="protocolTypes" /> + <xsd:attribute name="email_from" type="xsd:string" /> + <xsd:attribute name="url" type="xsd:string" /> + <xsd:attribute name="options" type="xsd:string" /> + <xsd:attribute name="destination" type="xsd:string" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="endpointConfiguration"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="name" type="xsd:string" + nillable="true" /> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + <xsd:element name="antispamConfiguration"> + <xsd:complexType> + <xsd:sequence minOccurs="1" maxOccurs="unbounded"> + <xsd:element name="source" type="xsd:string" /> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + <xsd:element name="cacheConfiguration"> + <xsd:complexType> + <xsd:sequence minOccurs="1" maxOccurs="unbounded"> + <xsd:element name="resource" type="xsd:string" /> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + <xsd:element name="dpiConfiguration"> + <xsd:complexType> + <xsd:sequence minOccurs="1" maxOccurs="unbounded"> + <xsd:element name="notAllowed" type="xsd:string" /> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + <xsd:element name="mailclientConfiguration"> + <xsd:complexType> + <xsd:attribute name="mailserver" type="xsd:string" + use="required" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="mailserverConfiguration"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="name" type="xsd:string" + nillable="true" /> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + <xsd:element name="natConfiguration"> + <xsd:complexType> + <xsd:sequence minOccurs="1" maxOccurs="unbounded"> + <xsd:element name="source" type="xsd:string" /> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + <xsd:element name="vpnaccessConfiguration"> + <xsd:complexType> + <xsd:attribute name="vpnexit" type="xsd:string" + use="required" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="vpnexitConfiguration"> + <xsd:complexType> + <xsd:attribute name="vpnaccess" type="xsd:string" + use="required" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="webclientConfiguration"> + <xsd:complexType> + <xsd:attribute name="nameWebServer" type="xsd:string" + use="required" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="webserverConfiguration"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="name" type="xsd:string" + nillable="true" /> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + <xsd:element name="fieldmodifierConfiguration"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="name" type="xsd:string" + nillable="true" /> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + + <xsd:simpleType name="functionalTypes"> + <xsd:restriction base="xsd:string"> + <xsd:enumeration value="FIREWALL" /> + <xsd:enumeration value="ENDHOST" /> + <xsd:enumeration value="ENDPOINT" /> + <xsd:enumeration value="ANTISPAM" /> + <xsd:enumeration value="CACHE" /> + <xsd:enumeration value="DPI" /> + <xsd:enumeration value="MAILCLIENT" /> + <xsd:enumeration value="MAILSERVER" /> + <xsd:enumeration value="NAT" /> + <xsd:enumeration value="VPNACCESS" /> + <xsd:enumeration value="VPNEXIT" /> + <xsd:enumeration value="WEBCLIENT" /> + <xsd:enumeration value="WEBSERVER" /> + <xsd:enumeration value="FIELDMODIFIER" /> + </xsd:restriction> + </xsd:simpleType> + <xsd:simpleType name="protocolTypes"> + <xsd:restriction base="xsd:string"> + <xsd:enumeration value="HTTP_REQUEST" /> + <xsd:enumeration value="HTTP_RESPONSE" /> + <xsd:enumeration value="POP3_REQUEST" /> + <xsd:enumeration value="POP3_RESPONSE" /> + </xsd:restriction> + </xsd:simpleType> + + --> + +</xsd:schema>
\ No newline at end of file diff --git a/verigraph/schema/tosca/ToscaVerigraphDefinitions.xml b/verigraph/schema/tosca/ToscaVerigraphDefinitions.xml new file mode 100644 index 0000000..4f49037 --- /dev/null +++ b/verigraph/schema/tosca/ToscaVerigraphDefinitions.xml @@ -0,0 +1,77 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (c) 2018 Politecnico di Torino and others. + + All rights reserved. This program and the accompanying materials + are made available under the terms of the Apache License, Version 2.0 + which accompanies this distribution, and is available at + http://www.apache.org/licenses/LICENSE-2.0 +--> + +<Definitions id="Verigraph_Definitions" name="Verigraph Type Definition" + xmlns="http://docs.oasis-open.org/tosca/ns/2011/12" + targetNamespace="http://docs.oasis-open.org/tosca/ns/2011/12/ToscaVerigraphDefinition"> + + <import importType="http://www.w3.org/2001/XMLSchema" + namespace="http://docs.oasis-open.org/tosca/ns/2011/12/ToscaVerigraphDefinition" + location="./ToscaTypes_XMLconfig.xsd" /> + + <NodeType name="AntispamType"> + <PropertiesDefinition element="Configuration" /> + </NodeType> + + <NodeType name="CacheType"> + <PropertiesDefinition element="Configuration" /> + </NodeType> + + <NodeType name="DpiType"> + <PropertiesDefinition element="Configuration" /> + </NodeType> + + <NodeType name="EndhostType"> + <PropertiesDefinition element="Configuration" /> + </NodeType> + + <NodeType name="EndpointType"> + <PropertiesDefinition element="Configuration" /> + </NodeType> + + <NodeType name="FieldModifierType"> + <PropertiesDefinition element="Configuration" /> + </NodeType> + + <NodeType name="FirewallType"> + <PropertiesDefinition element="Configuration" /> + </NodeType> + + <NodeType name="MailclientType"> + <PropertiesDefinition element="Configuration" /> + </NodeType> + + <NodeType name="MailserverType"> + <PropertiesDefinition element="Configuration" /> + </NodeType> + + <NodeType name="NatType"> + <PropertiesDefinition element="Configuration" /> + </NodeType> + + <NodeType name="VpnAccessType"> + <PropertiesDefinition element="Configuration" /> + </NodeType> + + <NodeType name="VpnExitType"> + <PropertiesDefinition element="Configuration" /> + </NodeType> + + <NodeType name="WebclientType"> + <PropertiesDefinition element="Configuration" /> + </NodeType> + + <NodeType name="WebserverType"> + <PropertiesDefinition element="Configuration" /> + </NodeType> + + <RelationshipType name="linkedTo" /> + +</Definitions>
\ No newline at end of file diff --git a/verigraph/schema/tosca/yamlToscaDefinitions.yaml b/verigraph/schema/tosca/yamlToscaDefinitions.yaml new file mode 100644 index 0000000..e72a5da --- /dev/null +++ b/verigraph/schema/tosca/yamlToscaDefinitions.yaml @@ -0,0 +1,157 @@ +############################################################################## +# Copyright (c) 2018 Politecnico di Torino and others. +# +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Apache License, Version 2.0 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################## + +#Tosca definitions for Verigraph extension in Tosca Yaml simple profile + +tosca_definitions_version: http://docs.oasis-open.org/tosca/ns/simple/yaml/1.0 + +description: node type definitions exetending tosca types for support to Verigraph verification system + +node_types: + verigraph.types.Antispam: + derived_from: tosca.nodes.Root + description: verigraph Antispam node + properties: + sources: + type: list + entry_schema: + type: string + + verigraph.types.Cache: + derived_from: tosca.nodes.Root + description: verigraph Cache node + properties: + resources: + type: list + entry_schema: + type: string + + verigraph.types.Dpi: + derived_from: tosca.nodes.Root + description: verigraph Dpi node + properties: + notAllowedList: + type: list + entry_schema: + type: string + + verigraph.types.Endhost: + derived_from: tosca.nodes.Root + description: verigraph endhost node + attributes: + body: + type: string + sequence: + type: integer + protocol: + type: string + constraints: + - valid_values: [ HTTP_REQUEST, HTTP_RESPONSE, POP3_REQUEST, POP3_RESOPONSE ] + email_from: + type: string + url: + type: string + options: + type: string + destination: + type: string + + verigraph.types.Endpoint: + derived_from: tosca.nodes.Root + description: verigraph Endpoint node + properties: + names: + type: list + entry_schema: + type: string + + verigraph.types.FieldModifier: + derived_from: tosca.nodes.Root + description: verigraph Field Modifier node + properties: + names: + type: list + entry_schema: + type: string + + verigraph.types.Firewall: + derived_from: tosca.nodes.Root + description: verigraph Firewall node + properties: + elements: + type: map + entry_schema: + description: "source : destination" firewall mapping + type: string + + verigraph.types.MailClient: + derived_from: tosca.nodes.Root + description: verigraph Mail Client node + attributes: + mailserver: + type: string + + verigraph.types.MailServer: + derived_from: tosca.nodes.Root + descrtiption: verigraph Mail Server node + properties: + names: + type: list + entry_schema: + type: string + + verigraph.types.Nat: + derived_from: tosca.nodes.Root + descrtiption: verigraph Nat node + properties: + sources: + type: list + entry_schema: + type: string + + verigraph.types.VpnAccess: + deriver_from: tosca.nodes.Root + descrtiption: verigraph Vpn Access node + attributes: + vpnexit: + type: string + + verigraph.types.VpnExit: + derived_from: tosca.nodes.Root + descrtiption: verigraph Vpn Exit node + attributes: + vpnaccess: + type: string + + verigraph.types.WebClient: + derived_from: tosca.nodes.Root + descrtiption: verigraph web Client node + attributes: + nameWebServer: + type: string + + verigraph.types.WebServer: + derived_from: tosca.nodes.Root + descrtiption: verigraph web Server node + properties: + names: + type: list + entry_schema: + type: string + +relationship_types: + verigraph.relationshipType.generic: + derived_from: tosca.relationships.Root + properties: + name: + type: string + source_id: + type: string + target_id: + type: string diff --git a/verigraph/src/it/polito/verigraph/exception/InvalidServiceTemplateException.java b/verigraph/src/it/polito/verigraph/exception/InvalidServiceTemplateException.java new file mode 100644 index 0000000..b5fb868 --- /dev/null +++ b/verigraph/src/it/polito/verigraph/exception/InvalidServiceTemplateException.java @@ -0,0 +1,18 @@ +/*******************************************************************************
+ * Copyright (c) 2018 Politecnico di Torino and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Apache License, Version 2.0
+ * which accompanies this distribution, and is available at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+package it.polito.verigraph.exception;
+
+public class InvalidServiceTemplateException extends RuntimeException {
+
+ private static final long serialVersionUID = -3138131670694139585L;
+
+ public InvalidServiceTemplateException(String message) {
+ super(message);
+ }
+}
diff --git a/verigraph/src/it/polito/verigraph/exception/InvalidServiceTemplateExceptionMapper.java b/verigraph/src/it/polito/verigraph/exception/InvalidServiceTemplateExceptionMapper.java new file mode 100644 index 0000000..e796119 --- /dev/null +++ b/verigraph/src/it/polito/verigraph/exception/InvalidServiceTemplateExceptionMapper.java @@ -0,0 +1,29 @@ +/*******************************************************************************
+ * Copyright (c) 2018 Politecnico di Torino and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Apache License, Version 2.0
+ * which accompanies this distribution, and is available at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+package it.polito.verigraph.exception;
+
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.Response.Status;
+import javax.ws.rs.ext.ExceptionMapper;
+import javax.ws.rs.ext.Provider;
+
+import it.polito.verigraph.model.ErrorMessage;
+
+@Provider
+public class InvalidServiceTemplateExceptionMapper implements ExceptionMapper<InvalidServiceTemplateException> {
+
+ @Override
+ public Response toResponse(InvalidServiceTemplateException exception) {
+ ErrorMessage errorMessage = new ErrorMessage( exception.getMessage(),
+ 400,
+ "http://localhost:8080/verigraph/api-docs/");
+ return Response.status(Status.BAD_REQUEST).entity(errorMessage).build();
+ }
+
+}
\ No newline at end of file diff --git a/verigraph/src/it/polito/verigraph/grpc/client/ToscaClient.java b/verigraph/src/it/polito/verigraph/grpc/client/ToscaClient.java new file mode 100644 index 0000000..dbf8442 --- /dev/null +++ b/verigraph/src/it/polito/verigraph/grpc/client/ToscaClient.java @@ -0,0 +1,299 @@ +/*******************************************************************************
+ * Copyright (c) 2018 Politecnico di Torino and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Apache License, Version 2.0
+ * which accompanies this distribution, and is available at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+package it.polito.verigraph.grpc.client;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+import io.grpc.ManagedChannel;
+import io.grpc.ManagedChannelBuilder;
+import io.grpc.StatusRuntimeException;
+import it.polito.verigraph.grpc.GetRequest;
+import it.polito.verigraph.grpc.GraphGrpc;
+import it.polito.verigraph.grpc.NewGraph;
+import it.polito.verigraph.grpc.NewTopologyTemplate;
+import it.polito.verigraph.grpc.NodeTemplateGrpc;
+import it.polito.verigraph.grpc.RequestID;
+import it.polito.verigraph.grpc.Status;
+import it.polito.verigraph.grpc.TopologyTemplateGrpc;
+import it.polito.verigraph.grpc.ToscaPolicy;
+import it.polito.verigraph.grpc.ToscaRequestID;
+import it.polito.verigraph.grpc.ToscaTestGrpc;
+import it.polito.verigraph.grpc.ToscaVerificationGrpc;
+import it.polito.verigraph.grpc.VerigraphGrpc;
+
+public class ToscaClient {
+
+ private final ManagedChannel channel;
+ private final VerigraphGrpc.VerigraphBlockingStub blockingStub;
+
+ public ToscaClient(String host, int port) {
+ this(ManagedChannelBuilder.forAddress(host, port).usePlaintext(true));
+ }
+
+ /** Construct client for accessing toscaVerigraph server using the existing channel. */
+ public ToscaClient(ManagedChannelBuilder<?> channelBuilder) {
+ channel = channelBuilder.build();
+ blockingStub = VerigraphGrpc.newBlockingStub(channel);
+ }
+
+ /** Close the channel */
+ public void shutdown() throws InterruptedException {
+ channel.shutdown().awaitTermination(5, TimeUnit.SECONDS);
+ }
+
+ /** Obtain a list of the available TopologyTemplates*/
+ public List<TopologyTemplateGrpc> getTopologyTemplates(){
+ List<TopologyTemplateGrpc> templates = new ArrayList<TopologyTemplateGrpc>();
+ GetRequest request = GetRequest.newBuilder().build();
+ boolean response_ok = true;
+
+ /*Iterates on received topology templates, prints on log file in case of errors*/
+ Iterator<TopologyTemplateGrpc> receivedTemplates;
+ try {
+ receivedTemplates = blockingStub.getTopologyTemplates(request);
+ System.out.println("++ Receiving TopologyTemplates...");
+ while(receivedTemplates.hasNext()) {
+ TopologyTemplateGrpc received = receivedTemplates.next();
+ if(received.getErrorMessage().equals("")) {
+ System.out.println("++ Correctly received TopologyTemplate --> id:" + received.getId());
+ templates.add(received);
+ } else
+ System.out.println("-- Received a TopologyTemplate with error: " + received.getErrorMessage());
+ }
+ } catch (StatusRuntimeException ex) {
+ System.out.println("-- RPC failed: " + ex.getMessage());
+ response_ok = false;
+ }
+ if(response_ok) {
+ System.out.println("++ All TopologyTemplates correctly received.");
+ return templates;
+ } else {
+ return null; //Function returns null in case of error to differentiate from empty list case.
+ }
+ }
+
+
+ /** Obtain a TopologyTemplate by ID */
+ public TopologyTemplateGrpc getTopologyTemplate(String id) {
+ ToscaRequestID request = ToscaRequestID.newBuilder().setIdTopologyTemplate(id).build();
+ TopologyTemplateGrpc response = TopologyTemplateGrpc.newBuilder().build();
+ try {
+ System.out.println("++ Receiving TopologyTemplate...");
+ response = blockingStub.getTopologyTemplate(request);
+ if(response.getErrorMessage().equals("")){
+ System.out.println("++ Received TopologyTemplate --> id:" + response.getId());
+ return response;
+ } else {
+ System.out.println("-- Error: " + response.getErrorMessage());
+ return response;
+ }
+ } catch (StatusRuntimeException ex) {
+ System.out.println("-- RPC failed: " + ex.getStatus());
+ return TopologyTemplateGrpc.newBuilder().setErrorMessage(ex.getStatus().getDescription()).build();
+ }
+ }
+
+
+ /** Creates a new TopologyTemplate, takes in input a TopologyTemplateGrpc */
+ public NewTopologyTemplate createTopologyTemplate(TopologyTemplateGrpc topol) {
+ try {
+ //Sending new Topology and analyzing response
+ System.out.println("++ Sending the new TopologyTemplate...");
+ NewTopologyTemplate response = blockingStub.createTopologyTemplate(topol);
+ if(response.getSuccess())
+ System.out.println("++ TopologyTemplate successfully created with id: "+ response.getTopologyTemplate().getId());
+ else
+ System.out.println("-- TopologyTemplate creation failed: " + response.getErrorMessage());
+ return response;
+
+ } catch (StatusRuntimeException ex) {
+ System.out.println("-- RPC failed: " + ex.getStatus());
+ return NewTopologyTemplate.newBuilder().setSuccess(false).setErrorMessage(ex.getStatus().getDescription()).build();
+ //getDescription may be empty
+ }
+ }
+
+
+ /** Update a TopologyTemplate, takes in input a TopologyTemplateGrpc and the Topology's ID to be updated*/
+ public NewTopologyTemplate updateTopologyTemplate(TopologyTemplateGrpc topol, String id) {
+ //Checking if the inserted string is an object
+ try {
+ Long.valueOf(id);
+ } catch (NumberFormatException ex) {
+ System.out.println("-- The ID must a number according to Verigraph implementation.");
+ return NewTopologyTemplate.newBuilder().setSuccess(false)
+ .setErrorMessage("The ID must a number according to Verigraph implementation.").build();
+ }
+
+ //Update the topology ID
+ TopologyTemplateGrpc.Builder updTopol = TopologyTemplateGrpc.newBuilder();
+ try {
+ updTopol.setId(id)
+ .addAllNodeTemplate(topol.getNodeTemplateList())
+ .addAllRelationshipTemplate(topol.getRelationshipTemplateList());
+ } catch (Exception ex) {
+ System.out.println("-- Error: Incorrect fields implementation.");
+ return NewTopologyTemplate.newBuilder().setSuccess(false).setErrorMessage("Error: Incorrect fields implementation.").build();
+ }
+
+ //Sending updated Topology and analyzing response
+ try {
+
+ System.out.println("++ Sending the updated TopologyTemplate...");
+ NewTopologyTemplate response = blockingStub.updateTopologyTemplate(updTopol.build());
+ if(response.getSuccess())
+ System.out.println("++ TopologyTemplate successfully updated.");
+ else
+ System.out.println("-- TopologyTemplate not updated: " + response.getErrorMessage());
+ return response;
+
+ } catch (StatusRuntimeException ex) {
+ System.out.println("-- RPC failed: " + ex.getStatus());
+ return NewTopologyTemplate.newBuilder().setSuccess(false).setErrorMessage(ex.getStatus().getDescription()).build();
+ }
+ }
+
+
+ /** Delete a TopologyTemplate by ID */
+ public Status deleteTopologyTemplate(String id) {
+ try {
+ Long.valueOf(id);
+ } catch (NumberFormatException ex) {
+ System.out.println("-- The ID must a number according to Verigraph implementation.");
+ return Status.newBuilder().setSuccess(false)
+ .setErrorMessage("The ID must a number according to Verigraph implementation.").build();
+ }
+ ToscaRequestID request = ToscaRequestID.newBuilder().setIdTopologyTemplate(id).build();
+ try {
+ System.out.println("++ Sending delete request...");
+ Status response = blockingStub.deleteTopologyTemplate(request);
+ if(response.getSuccess())
+ System.out.println("++ TopologyTemplate successfully deleted.");
+ else
+ System.out.println("-- Error deleting TopologyTemplate : " + response.getErrorMessage());
+ return response;
+
+ } catch (StatusRuntimeException ex) {
+ System.out.println("-- RPC failed: " + ex.getStatus());
+ return Status.newBuilder().setSuccess(false).setErrorMessage(ex.getStatus().getDescription()).build();
+ }
+ }
+
+
+ /** VerifyPolicy */
+ public ToscaVerificationGrpc verifyPolicy(ToscaPolicy policy){
+ ToscaVerificationGrpc response;
+ try {
+ System.out.println("++ Sending ToscaPolicy...");
+ response = blockingStub.verifyToscaPolicy(policy);
+ if(!response.getErrorMessage().equals("")){
+ System.out.println("-- Error in operation: " + response.getErrorMessage());
+ }
+ else {
+ System.out.println("++ Result: " + response.getResult());
+ System.out.println("++ Comment: " + response.getComment());
+
+ for(ToscaTestGrpc test : response.getTestList()){
+ System.out.println("++ Traversed nodes:");
+ for(NodeTemplateGrpc node : test.getNodeTemplateList()){
+ System.out.println("\t Node "+node.getName());
+ }
+ }
+ }
+ return response;
+ } catch (StatusRuntimeException e) {
+ System.out.println("-- RPC failed: " + e.getStatus());
+ return ToscaVerificationGrpc.newBuilder().setSuccessOfOperation(false)
+ .setErrorMessage(e.getStackTrace().toString()).build();
+ }
+ }
+
+
+ //Methods added for backward compatibility with JSON grpc, only create and update methods need to be redefined
+ //The reason is that the tosca Grpc converter requires a coherent numbering of IDs while the previous
+ //implementations exploits names to identify nodes and can considers IDs as not strictly required attributes.
+
+ public NewGraph createGraph(GraphGrpc gr) {
+ NewGraph response;
+ try {
+ response = blockingStub.createGraph(gr);
+ if(response.getSuccess())
+ System.out.println("++ TopologyTemplate successfully created with id: "+ response.getGraph().getId());
+ else
+ System.out.println("-- TopologyTemplate creation failed: " + response.getErrorMessage());
+ return response;
+ } catch (StatusRuntimeException e) {
+ System.err.println("-- RPC failed: " + e.getStatus());
+ return NewGraph.newBuilder().setSuccess(false).setErrorMessage(e.getStatus().getDescription()).build();
+ }
+
+ }
+
+ public NewGraph updateGraph(long idGraph, GraphGrpc newGraph) {
+
+ GraphGrpc gr = GraphGrpc.newBuilder(newGraph).setId(idGraph).build();
+ NewGraph response;
+ try {
+ response = blockingStub.updateGraph(gr);
+ if(response.getSuccess())
+ System.out.println("++ TopologyTemplate successfully created with id: "+ response.getGraph().getId());
+ else
+ System.out.println("-- TopologyTemplate creation failed: " + response.getErrorMessage());
+ return response;
+ } catch (StatusRuntimeException e) {
+ System.err.println("-- RPC failed: " + e.getStatus());
+ return NewGraph.newBuilder().setSuccess(false).setErrorMessage(e.getStatus().getDescription()).build();
+ }
+ }
+
+ public GraphGrpc getGraph(long idGraph) {
+
+ RequestID request = RequestID.newBuilder().setIdGraph(idGraph).build() ;
+ try {
+ System.out.println("++ Receiving TopologyTemplate...");
+ GraphGrpc graph = blockingStub.getGraph(request);
+ System.out.println("++ Received TopologyTemplate --> id:" + graph.getId());
+ if(!graph.getErrorMessage().equals("")){
+ System.out.println("-- Error : " + graph.getErrorMessage());
+ return graph;
+ }
+ return graph;
+ } catch (StatusRuntimeException ex) {
+ System.err.println("-- RPC failed: " + ex.getStatus());
+ return null;
+ }
+ }
+
+
+ public List<GraphGrpc> getGraphs() {
+ List<GraphGrpc> graphsReceived = new ArrayList<GraphGrpc>();
+ GetRequest request = GetRequest.newBuilder().build();
+ Iterator<GraphGrpc> graphs;
+ try {
+ graphs = blockingStub.getGraphs(request);
+ System.out.println("++ Receiving TopologyTemplates...");
+ while (graphs.hasNext()) {
+ GraphGrpc graph = graphs.next();
+ if(graph.getErrorMessage().equals("")){
+ System.out.println("++ Correctly received graph --> id:" + graph.getId());
+ graphsReceived.add(graph);
+ }else{
+ System.out.println("-- Received a graph with error : " + graph.getErrorMessage());
+ }
+ }
+ } catch (StatusRuntimeException ex) {
+ System.err.println("-- RPC failed : " + ex.getStatus());
+ return null;
+ }
+ return graphsReceived;
+ }
+}
diff --git a/verigraph/src/it/polito/verigraph/grpc/server/GrpcUtils.java b/verigraph/src/it/polito/verigraph/grpc/server/GrpcUtils.java index 43859db..96c52a5 100644 --- a/verigraph/src/it/polito/verigraph/grpc/server/GrpcUtils.java +++ b/verigraph/src/it/polito/verigraph/grpc/server/GrpcUtils.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2017 Politecnico di Torino and others. + * Copyright (c) 2017/18 Politecnico di Torino and others. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Apache License, Version 2.0 @@ -12,16 +12,18 @@ import java.io.IOException; import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; + import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.google.common.base.Splitter; + import it.polito.verigraph.grpc.ConfigurationGrpc; import it.polito.verigraph.grpc.GraphGrpc; import it.polito.verigraph.grpc.NeighbourGrpc; import it.polito.verigraph.grpc.NodeGrpc; +import it.polito.verigraph.grpc.NodeGrpc.FunctionalType; import it.polito.verigraph.grpc.TestGrpc; import it.polito.verigraph.grpc.VerificationGrpc; -import it.polito.verigraph.grpc.NodeGrpc.FunctionalType; import it.polito.verigraph.model.Configuration; import it.polito.verigraph.model.Graph; import it.polito.verigraph.model.Neighbour; @@ -29,6 +31,7 @@ import it.polito.verigraph.model.Node; import it.polito.verigraph.model.Test; import it.polito.verigraph.model.Verification; + public class GrpcUtils { private static final Logger logger = Logger.getLogger(GrpcUtils.class.getName()); @@ -43,6 +46,7 @@ public class GrpcUtils { //id is not present Neighbour ne = new Neighbour(); ne.setName(request.getName()); + ne.setId(request.getId()); return ne; } @@ -86,13 +90,17 @@ public class GrpcUtils { } public static Node deriveNode(NodeGrpc request) { - //id is not present + //id is not present Node node = new Node(); node.setName(request.getName()); node.setFunctional_type(request.getFunctionalType().toString()); Configuration conf = deriveConfiguration(request.getConfiguration()); node.setConfiguration(conf); + //Modification for Tosca CLI + Long id = request.getId(); + if( id != null) node.setId(request.getId()); + Map<Long,Neighbour> neighours = node.getNeighbours(); long i = 1; for(NeighbourGrpc neighbour:request.getNeighbourList()){ @@ -106,7 +114,7 @@ public class GrpcUtils { public static GraphGrpc obtainGraph(Graph graph){ GraphGrpc.Builder gr = GraphGrpc.newBuilder(); gr.setId(graph.getId()); - for(Node node:graph.getNodes().values()){ + for(Node node : graph.getNodes().values()){ NodeGrpc ng = obtainNode(node); gr.addNode(ng); } @@ -116,14 +124,16 @@ public class GrpcUtils { public static Graph deriveGraph(GraphGrpc request) { //id is not present Graph graph = new Graph(); - + //Modification for Tosca CLI + Long id = request.getId(); + if( id != null) graph.setId(request.getId()); + long i=1; Map<Long, Node> nodes= graph.getNodes(); for(NodeGrpc node:request.getNodeList()){ Node ng = deriveNode(node); - nodes.put(i++, ng); + nodes.put(i++, ng); } - return graph; } @@ -142,12 +152,13 @@ public class GrpcUtils { return ver.build(); } - /**Intended for string that begins with "?" - * */ + + /** Intended for string that begins with "?" */ public static Map<String,String> getParamGivenString(String str){ String string = str.substring(1); final Map<String, String> map = Splitter.on('&').trimResults().withKeyValueSeparator("="). split(string); return map; } + } diff --git a/verigraph/src/it/polito/verigraph/grpc/server/Service.java b/verigraph/src/it/polito/verigraph/grpc/server/Service.java index 1839b7e..c6b69b0 100644 --- a/verigraph/src/it/polito/verigraph/grpc/server/Service.java +++ b/verigraph/src/it/polito/verigraph/grpc/server/Service.java @@ -15,9 +15,13 @@ import java.util.logging.FileHandler; import java.util.logging.Level; import java.util.logging.Logger; import java.util.logging.SimpleFormatter; + import io.grpc.Server; import io.grpc.ServerBuilder; import io.grpc.stub.StreamObserver; +import it.polito.verigraph.exception.BadRequestException; +import it.polito.verigraph.exception.DataNotFoundException; +import it.polito.verigraph.exception.ForbiddenException; import it.polito.verigraph.grpc.ConfigurationGrpc; import it.polito.verigraph.grpc.GetRequest; import it.polito.verigraph.grpc.GraphGrpc; @@ -25,15 +29,17 @@ import it.polito.verigraph.grpc.NeighbourGrpc; import it.polito.verigraph.grpc.NewGraph; import it.polito.verigraph.grpc.NewNeighbour; import it.polito.verigraph.grpc.NewNode; +import it.polito.verigraph.grpc.NewTopologyTemplate; import it.polito.verigraph.grpc.NodeGrpc; import it.polito.verigraph.grpc.Policy; import it.polito.verigraph.grpc.RequestID; import it.polito.verigraph.grpc.Status; +import it.polito.verigraph.grpc.TopologyTemplateGrpc; +import it.polito.verigraph.grpc.ToscaPolicy; +import it.polito.verigraph.grpc.ToscaRequestID; +import it.polito.verigraph.grpc.ToscaVerificationGrpc; import it.polito.verigraph.grpc.VerificationGrpc; import it.polito.verigraph.grpc.VerigraphGrpc; -import it.polito.verigraph.exception.BadRequestException; -import it.polito.verigraph.exception.DataNotFoundException; -import it.polito.verigraph.exception.ForbiddenException; import it.polito.verigraph.model.Configuration; import it.polito.verigraph.model.Graph; import it.polito.verigraph.model.Neighbour; @@ -44,6 +50,8 @@ import it.polito.verigraph.service.GraphService; import it.polito.verigraph.service.NeighbourService; import it.polito.verigraph.service.NodeService; import it.polito.verigraph.service.VerificationService; +import it.polito.verigraph.tosca.converter.grpc.GraphToGrpc; +import it.polito.verigraph.tosca.converter.grpc.GrpcToGraph; public class Service { /** Port on which the server should run. */ @@ -107,7 +115,7 @@ public class Service { } } - /**Here start method of my implementation*/ + /** Here start methods */ private class VerigraphImpl extends VerigraphGrpc.VerigraphImplBase{ /** Here start methods of GraphResource*/ @@ -307,8 +315,7 @@ public class Service { @Override public void updateNode(NodeGrpc request, StreamObserver<NewNode> responseObserver) { - NewNode.Builder response = NewNode.newBuilder(); - try{ + NewNode.Builder response = NewNode.newBuilder(); try{ Node node = GrpcUtils.deriveNode(request); node.setId(request.getId()); Node newNode = nodeService.updateNode(request.getIdGraph(), node); @@ -340,7 +347,8 @@ public class Service { } Node node = nodeService.getNode(request.getIdGraph(), request.getIdNode()); if (node == null){ - throw new BadRequestException("Node with id " + request.getIdNode() + " not found in graph with id " + request.getIdGraph()); + throw new BadRequestException("Node with id " + request.getIdNode() + + " not found in graph with id " + request.getIdGraph()); } Configuration nodeConfiguration = GrpcUtils.deriveConfiguration(request); Node nodeCopy = new Node(); @@ -386,8 +394,7 @@ public class Service { NeighbourGrpc nr = NeighbourGrpc.newBuilder().setErrorMessage(internalError).build(); responseObserver.onNext(nr); logger.log(Level.WARNING, ex.getMessage()); - } - responseObserver.onCompleted(); + } responseObserver.onCompleted(); } @Override @@ -462,5 +469,149 @@ public class Service { responseObserver.onNext(response.build()); responseObserver.onCompleted(); } + + /** Here start methods of TOSCA gRPC server */ @Override + public void getTopologyTemplates (GetRequest request, StreamObserver<TopologyTemplateGrpc> responseObserver) { + boolean not_correct = false; + try { + for(Graph item : graphService.getAllGraphs()) { + TopologyTemplateGrpc topol = GraphToGrpc.obtainTopologyTemplate(item); + responseObserver.onNext(topol); + } + } catch(Exception ex){ + logger.log(Level.WARNING, ex.getMessage()); + not_correct = true; + } + if(not_correct) + responseObserver.onNext(TopologyTemplateGrpc.newBuilder() + .setErrorMessage("Internal Server Error while retrieving TopologyTemplate").build()); + responseObserver.onCompleted(); + } + + @Override + public void getTopologyTemplate (ToscaRequestID request, StreamObserver<TopologyTemplateGrpc> responseObserver) { + try { + Long graphID = Long.valueOf(request.getIdTopologyTemplate()); + //this method will throw a NumberFormatException in case the ID is not representable as a long + Graph graph = graphService.getGraph(graphID); + TopologyTemplateGrpc topol = GraphToGrpc.obtainTopologyTemplate(graph); + responseObserver.onNext(topol); + } catch(ForbiddenException | DataNotFoundException ex) { + TopologyTemplateGrpc topolError = TopologyTemplateGrpc.newBuilder().setErrorMessage(ex.getMessage()).build(); + responseObserver.onNext(topolError); + logger.log(Level.WARNING, ex.getMessage()); + } catch(NumberFormatException ex) { + TopologyTemplateGrpc topolError = TopologyTemplateGrpc.newBuilder() + .setErrorMessage("The TopologyTemplate ID must be a long value.").build(); + responseObserver.onNext(topolError); + logger.log(Level.WARNING, ex.getMessage()); + } catch(Exception ex) { + TopologyTemplateGrpc topolError = TopologyTemplateGrpc.newBuilder().setErrorMessage(internalError).build(); + responseObserver.onNext(topolError); + logger.log(Level.WARNING, ex.getMessage()); + } + responseObserver.onCompleted(); + } + + @Override + public void createTopologyTemplate (TopologyTemplateGrpc request, StreamObserver<NewTopologyTemplate> responseObserver) { + NewTopologyTemplate.Builder response = NewTopologyTemplate.newBuilder(); + try{ + Graph graph = GrpcToGraph.deriveGraph(request); + Graph newGraph = graphService.addGraph(graph); + response.setSuccess(true).setTopologyTemplate(GraphToGrpc.obtainTopologyTemplate(newGraph)); + } catch(BadRequestException ex) { + ex.printStackTrace(); + response.setSuccess(false).setErrorMessage("Provided invalid request to the service."); + logger.log(Level.WARNING, ex.getClass().toString()); + logger.log(Level.WARNING, ex.getMessage()); + } catch(Exception ex) { + ex.printStackTrace(); + response.setSuccess(false).setErrorMessage(internalError); + logger.log(Level.WARNING, ex.getClass().toString()); + logger.log(Level.WARNING, ex.getMessage()); + } + responseObserver.onNext(response.build()); + responseObserver.onCompleted(); + } + + + @Override + public void updateTopologyTemplate (TopologyTemplateGrpc request, StreamObserver<NewTopologyTemplate> responseObserver) { + NewTopologyTemplate.Builder response = NewTopologyTemplate.newBuilder(); + try{ + Graph graph = GrpcToGraph.deriveGraph(request); + Graph newGraph = graphService.updateGraph(graph); + response.setSuccess(true).setTopologyTemplate(GraphToGrpc.obtainTopologyTemplate(newGraph)); + } catch(ForbiddenException | DataNotFoundException | BadRequestException ex){ + response.setSuccess(false).setErrorMessage(ex.getMessage()); + logger.log(Level.WARNING, ex.getMessage()); + } catch(Exception ex){ + response.setSuccess(false).setErrorMessage(internalError); + logger.log(Level.WARNING, ex.getMessage()); + } + responseObserver.onNext(response.build()); + responseObserver.onCompleted(); + } + + + @Override + public void deleteTopologyTemplate (ToscaRequestID request, StreamObserver<Status> responseObserver) { + Status.Builder response = Status.newBuilder(); + Long graphID = null; + try{ + graphID = Long.valueOf(request.getIdTopologyTemplate()); + //this method will throw a NumberFormatException in case the ID is not representable as a long + graphService.removeGraph(graphID); + response.setSuccess(true); + } catch(ForbiddenException | DataNotFoundException ex) { + response.setSuccess(false).setErrorMessage(ex.getMessage()); + logger.log(Level.WARNING, ex.getMessage()); + } catch(NumberFormatException ex) { + response.setSuccess(false).setErrorMessage("The TopologyTemplate ID must be a long value."); + logger.log(Level.WARNING, ex.getMessage()); + } catch(Exception ex) { + response.setSuccess(false).setErrorMessage(internalError); + logger.log(Level.WARNING, ex.getMessage()); + } + responseObserver.onNext(response.build()); + responseObserver.onCompleted(); + } + + + @Override + public void verifyToscaPolicy(ToscaPolicy request, StreamObserver<ToscaVerificationGrpc> responseObserver) { + try{ + //Convert request + VerificationBean verify = new VerificationBean(); + verify.setDestination(request.getDestination()); + verify.setSource(request.getSource()); + verify.setType(request.getType().toString()); + verify.setMiddlebox(request.getMiddlebox()); + + //Convert Response + Long graphID = Long.valueOf(request.getIdTopologyTemplate()); + //this method will throw a NumberFormatException in case the ID is not representable as a long + Verification ver = verificationService.verify(graphID, verify); + responseObserver.onNext(GraphToGrpc.obtainToscaVerification(ver)); + } catch(ForbiddenException | DataNotFoundException | BadRequestException ex) { + ToscaVerificationGrpc verError = ToscaVerificationGrpc.newBuilder().setSuccessOfOperation(false) + .setErrorMessage(ex.getMessage()).build(); + responseObserver.onNext(verError); + logger.log(Level.WARNING, ex.getMessage()); + } catch(NumberFormatException ex) { + ToscaVerificationGrpc verError = ToscaVerificationGrpc.newBuilder().setSuccessOfOperation(false) + .setErrorMessage("The TopologyTemplate ID must be a long value.").build(); + responseObserver.onNext(verError); + logger.log(Level.WARNING, ex.getMessage()); + } catch(Exception ex) { + ToscaVerificationGrpc verError = ToscaVerificationGrpc.newBuilder().setSuccessOfOperation(false) + .setErrorMessage(internalError).build(); + responseObserver.onNext(verError); + logger.log(Level.WARNING, ex.getMessage()); + } responseObserver.onCompleted(); + } + + } } diff --git a/verigraph/src/it/polito/verigraph/grpc/tosca/test/GrpcToscaTest.java b/verigraph/src/it/polito/verigraph/grpc/tosca/test/GrpcToscaTest.java new file mode 100644 index 0000000..5771406 --- /dev/null +++ b/verigraph/src/it/polito/verigraph/grpc/tosca/test/GrpcToscaTest.java @@ -0,0 +1,425 @@ +/*******************************************************************************
+ * Copyright (c) 2018 Politecnico di Torino and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Apache License, Version 2.0
+ * which accompanies this distribution, and is available at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+package it.polito.verigraph.grpc.tosca.test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.fail;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+import org.junit.runners.MethodSorters;
+
+import it.polito.verigraph.grpc.NewTopologyTemplate;
+import it.polito.verigraph.grpc.NodeTemplateGrpc;
+import it.polito.verigraph.grpc.NodeTemplateGrpc.Type;
+import it.polito.verigraph.grpc.RelationshipTemplateGrpc;
+import it.polito.verigraph.grpc.Status;
+import it.polito.verigraph.grpc.TopologyTemplateGrpc;
+import it.polito.verigraph.grpc.ToscaConfigurationGrpc;
+import it.polito.verigraph.grpc.ToscaPolicy;
+import it.polito.verigraph.grpc.ToscaPolicy.PolicyType;
+import it.polito.verigraph.grpc.ToscaVerificationGrpc;
+import it.polito.verigraph.grpc.client.ToscaClient;
+import it.polito.verigraph.grpc.server.Service;
+
+@RunWith(JUnit4.class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+public class GrpcToscaTest {
+ private Service server;
+ private ToscaClient client;
+ private TopologyTemplateGrpc testTemplate, simpleTestTemplate;
+
+ public GrpcToscaTest() {
+ this.generateTestTemplate();
+ }
+
+ @Before
+ public void setUpBeforeClass() throws Exception {
+ client = new ToscaClient("localhost" , 50051);
+ server = new Service(50051);
+ server.start();
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ server.stop();
+ client.shutdown();
+ }
+
+
+ @Test
+ public void test0Creation() {
+ System.out.println("\nTest A: Graph Creation.");
+
+ NewTopologyTemplate response = client.createTopologyTemplate(testTemplate);
+ assertNotNull("Returned a NULL graph", response);
+ assertEquals(response.getSuccess(), true);
+ assertEquals("Error report: " + response.getErrorMessage(), "", response.getErrorMessage());
+
+ Status resp = client.deleteTopologyTemplate(response.getTopologyTemplate().getId());
+ assertEquals("Error while deleting testTemplate.", true, resp.getSuccess());
+
+ System.out.println("Test A completed\n");
+
+ return;
+ }
+
+
+ @Test
+ public void test1Reading() {
+ System.out.println("\nTest B: Graph Reading.");
+
+ //Creating a test graph on remote repository
+ System.out.println("Phase B.1 -- Creating a test graph.");
+ NewTopologyTemplate response = client.createTopologyTemplate(simpleTestTemplate);
+ assertNotNull("Returned a NULL graph", response);
+ assertEquals(true, response.getSuccess());
+ assertEquals("Error report: " + response.getErrorMessage(), "", response.getErrorMessage());
+
+ //Reading remote graph.
+ System.out.println("Phase B.2 -- Reading remote graph.");
+ TopologyTemplateGrpc retrieved = client.getTopologyTemplate(response.getTopologyTemplate().getId());
+ assertNotNull("Retrieved a NULL graph", retrieved);
+ assertEquals(retrieved.getId(), response.getTopologyTemplate().getId());
+
+ //Nodes checking
+ System.out.println("Phase B.3 -- Checking graph's nodes.");
+ assertEquals(retrieved.getNodeTemplateCount(), 3);
+ assertEquals("Node1 name error", response.getTopologyTemplate().getNodeTemplateList().get(0).getName(),
+ retrieved.getNodeTemplateList().get(0).getName());
+ assertEquals("Node2 name error", response.getTopologyTemplate().getNodeTemplateList().get(1).getName(),
+ retrieved.getNodeTemplateList().get(1).getName());
+ assertEquals("Node3 name error", response.getTopologyTemplate().getNodeTemplateList().get(2).getName(),
+ retrieved.getNodeTemplateList().get(2).getName());
+
+ //Relationships checking
+ System.out.println("Phase B.4 -- Checking graph's relationships.");
+ assertEquals(retrieved.getRelationshipTemplateCount(), 4);
+ String source1=null, target1=null;
+ String source2=null, target2=null;
+ String source3=null, target3=null;
+ String source4=null, target4=null;
+ for (NodeTemplateGrpc node : retrieved.getNodeTemplateList()){
+ if(node.getId().equals(retrieved.getRelationshipTemplateList().get(0).getIdSourceNodeTemplate()))
+ source1=node.getName();
+ if(node.getId().equals(retrieved.getRelationshipTemplateList().get(0).getIdTargetNodeTemplate()))
+ target1=node.getName();
+ if(node.getId().equals(retrieved.getRelationshipTemplateList().get(1).getIdSourceNodeTemplate()))
+ source2=node.getName();
+ if(node.getId().equals(retrieved.getRelationshipTemplateList().get(1).getIdTargetNodeTemplate()))
+ target2=node.getName();
+ if(node.getId().equals(retrieved.getRelationshipTemplateList().get(2).getIdSourceNodeTemplate()))
+ source3=node.getName();
+ if(node.getId().equals(retrieved.getRelationshipTemplateList().get(2).getIdTargetNodeTemplate()))
+ target3=node.getName();
+ if(node.getId().equals(retrieved.getRelationshipTemplateList().get(3).getIdSourceNodeTemplate()))
+ source4=node.getName();
+ if(node.getId().equals(retrieved.getRelationshipTemplateList().get(3).getIdTargetNodeTemplate()))
+ target4=node.getName();
+ }
+
+ assertEquals("Relat1 name error", retrieved.getRelationshipTemplateList().get(0).getName(), source1+"to"+target1);
+ assertEquals("Relat2 name error", retrieved.getRelationshipTemplateList().get(1).getName(), source2+"to"+target2);
+ assertEquals("Relat3 name error", retrieved.getRelationshipTemplateList().get(2).getName(), source3+"to"+target3);
+ assertEquals("Relat4 name error", retrieved.getRelationshipTemplateList().get(3).getName(), source4+"to"+target4);
+
+ System.out.println("Phase B.5 -- Deleting graph.");
+ Status resp = client.deleteTopologyTemplate(response.getTopologyTemplate().getId());
+ assertEquals("Error while deleting simpleTestTemplate", true, resp.getSuccess());
+
+
+ System.out.println("Test B completed.\n");
+ return;
+ }
+
+ @Test
+ public void test2Update() {
+ System.out.println("\nTest C: Update.");
+
+ //Creating a test graph on remote repository
+ System.out.println("Phase C.1 -- Creating a test graph.");
+ NewTopologyTemplate response = client.createTopologyTemplate(simpleTestTemplate);
+ assertNotNull("Returned a NULL graph", response);
+ assertEquals(true, response.getSuccess());
+ assertEquals("Error report: " + response.getErrorMessage(), "", response.getErrorMessage());
+
+ //Reading remote graph.
+ System.out.println("Phase C.2 -- Reading remote graph.");
+ TopologyTemplateGrpc retrieved = client.getTopologyTemplate(response.getTopologyTemplate().getId());
+ assertNotNull("Retrieved a NULL graph", retrieved);
+ assertEquals(retrieved.getId(), response.getTopologyTemplate().getId());
+
+ //Updating a TopologyTemplateGrpc
+ System.out.println("Phase C.3 -- Updating a test graph.");
+ TopologyTemplateGrpc.Builder templ = TopologyTemplateGrpc.newBuilder();
+ List<NodeTemplateGrpc> nodes = new ArrayList<NodeTemplateGrpc>();
+ List<RelationshipTemplateGrpc> relats = new ArrayList<RelationshipTemplateGrpc>();
+
+ ToscaConfigurationGrpc node1conf = ToscaConfigurationGrpc.newBuilder().setDescription("node1configuration")
+ .setId("15").setConfiguration("[]").build();
+ NodeTemplateGrpc node1 = NodeTemplateGrpc.newBuilder().setConfiguration(node1conf).setId("999")
+ .setName("webserver1").setType(Type.webserver).build();
+ nodes.add(node1);
+
+ ToscaConfigurationGrpc node2conf = ToscaConfigurationGrpc.newBuilder().setDescription("node2configuration")
+ .setId("16").setConfiguration("[{\r\n\"protocol\":\"HTTP_REQUEST\",\r\n \"url\":\"www.facebook.com\"\r\n }]").build();
+ NodeTemplateGrpc node2 = NodeTemplateGrpc.newBuilder().setConfiguration(node2conf).setId("888")
+ .setName("host2").setType(Type.endhost).build();
+ nodes.add(node2);
+
+ RelationshipTemplateGrpc rel0 = RelationshipTemplateGrpc.newBuilder().setId("1001")
+ .setIdSourceNodeTemplate("999").setIdTargetNodeTemplate("888").setName("webserver1tohost2").build();
+ relats.add(rel0);
+
+ RelationshipTemplateGrpc rel1 = RelationshipTemplateGrpc.newBuilder().setId("1002")
+ .setIdSourceNodeTemplate("888").setIdTargetNodeTemplate("999").setName("host2towebserver1").build();
+ relats.add(rel1);
+
+ TopologyTemplateGrpc newTestTemplate = templ.addAllNodeTemplate(nodes).addAllRelationshipTemplate(relats).setId("9").build();
+ NewTopologyTemplate updated = client.updateTopologyTemplate(newTestTemplate, response.getTopologyTemplate().getId());
+ assertNotNull("Returned a NULL graph", updated);
+ assertEquals(true, updated.getSuccess());
+ assertEquals("Error report: " + updated.getErrorMessage(), "", updated.getErrorMessage());
+
+ //Reading remote graph.
+ System.out.println("Phase C.4 -- Reading remote graph.");
+ TopologyTemplateGrpc retrieved2 = client.getTopologyTemplate(response.getTopologyTemplate().getId());
+ assertNotNull("Retrieved a NULL graph", retrieved2);
+ assertEquals(retrieved2.getId(), response.getTopologyTemplate().getId());
+
+ //Nodes checking
+ System.out.println("Phase C.5 -- Checking updated graph's nodes.");
+ assertEquals(retrieved2.getNodeTemplateCount(), 2);
+ assertEquals("Node1 name error", updated.getTopologyTemplate().getNodeTemplateList().get(0).getName(),
+ retrieved2.getNodeTemplateList().get(0).getName());
+ assertEquals("Node2 name error", updated.getTopologyTemplate().getNodeTemplateList().get(1).getName(),
+ retrieved2.getNodeTemplateList().get(1).getName());
+
+ //Relationships checking
+ System.out.println("Phase C.6 -- Checking updated graph's relationships.");
+ assertEquals(retrieved2.getRelationshipTemplateCount(), 2);
+ String source1=null, target1=null;
+ String source2=null, target2=null;
+ for (NodeTemplateGrpc node : retrieved2.getNodeTemplateList()){
+ if(node.getId().equals(retrieved2.getRelationshipTemplateList().get(0).getIdSourceNodeTemplate()))
+ source1=node.getName();
+ if(node.getId().equals(retrieved2.getRelationshipTemplateList().get(0).getIdTargetNodeTemplate()))
+ target1=node.getName();
+ if(node.getId().equals(retrieved2.getRelationshipTemplateList().get(1).getIdSourceNodeTemplate()))
+ source2=node.getName();
+ if(node.getId().equals(retrieved2.getRelationshipTemplateList().get(1).getIdTargetNodeTemplate()))
+ target2=node.getName();
+ }
+
+ assertEquals("Relat1 name error", retrieved2.getRelationshipTemplateList().get(0).getName(), source1+"to"+target1);
+ assertEquals("Relat2 name error", retrieved2.getRelationshipTemplateList().get(1).getName(), source2+"to"+target2);
+
+ System.out.println("Phase C.6 -- Deleting graph.");
+ Status resp = client.deleteTopologyTemplate(updated.getTopologyTemplate().getId());
+ assertEquals("Error while deleting simpleTestTemplate", true, resp.getSuccess());
+
+ System.out.println("Test C completed.\n");
+ return;
+ }
+
+
+ @Test
+ public void test3Verification() {
+ System.out.println("\nTest D: Verification.");
+ NewTopologyTemplate response = client.createTopologyTemplate(testTemplate);
+ if(response == null | response.getSuccess() != true) {
+ fail("Test failed, unable to load the graph.");
+ return;
+ }
+
+ //The Id of the graph on which we are going to perform tests
+ String testTemplateId = response.getTopologyTemplate().getId();
+
+ //REACHABILITY test
+ System.out.println("Phase 1.1 - Reachability SAT.");
+ ToscaPolicy policy = ToscaPolicy.newBuilder().setIdTopologyTemplate(testTemplateId)
+ .setType(PolicyType.reachability).setSource("host2").setDestination("host1").build();
+ ToscaVerificationGrpc result = client.verifyPolicy(policy);
+ assertNotNull("There was no response", result);
+ assertEquals("Unexpected result : " + result.getResult() + " - " + result.getComment(), "SAT", result.getResult());
+ assertEquals("Error report: " + result.getErrorMessage(), "", result.getErrorMessage());
+
+ result = null;
+ System.out.println("Phase 1.2 - Reachability UNSAT.");
+ policy = ToscaPolicy.newBuilder().setIdTopologyTemplate(testTemplateId)
+ .setType(PolicyType.reachability).setSource("host1").setDestination("antispamNode1").build();
+ result = client.verifyPolicy(policy);
+ assertNotNull("There was no response", result);
+ assertEquals("Unexpected result : " + result.getResult() + " - " + result.getComment(), "UNSAT", result.getResult());
+ assertEquals("Error report: " + result.getErrorMessage(), "", result.getErrorMessage());
+
+ //ISOLATION test
+ result = null;
+ System.out.println("Phase 2.1 - Isolation SAT.");
+ policy = ToscaPolicy.newBuilder().setIdTopologyTemplate(testTemplateId)
+ .setType(PolicyType.isolation).setSource("host2").setDestination("host1").setMiddlebox("webserver1").build();
+ result = client.verifyPolicy(policy);
+ assertNotNull("There was no response", result);
+ assertEquals("Unexpected result : " + result.getResult() + " - " + result.getComment(), "SAT", result.getResult());
+ assertEquals("Error report: " + result.getErrorMessage(), "", result.getErrorMessage());
+
+ System.out.println("Phase 2.2 - Isolation UNSAT.");
+ policy = ToscaPolicy.newBuilder().setIdTopologyTemplate(testTemplateId)
+ .setType(PolicyType.isolation).setSource("host2").setDestination("host1").setMiddlebox("fw").build();
+ result = client.verifyPolicy(policy);
+ assertNotNull("There was no response", result);
+ assertEquals("Unexpected result : " + result.getResult() + " - " + result.getComment(), "UNSAT", result.getResult());
+ assertEquals("Error report: " + result.getErrorMessage(), "", result.getErrorMessage());
+
+ //TRAVERSAL test
+ result = null;
+ System.out.println("Phase 3.1 - Traversal SAT.");
+ policy = ToscaPolicy.newBuilder().setIdTopologyTemplate(testTemplateId)
+ .setType(PolicyType.traversal).setSource("host2").setDestination("host1").setMiddlebox("fw").build();
+ result = client.verifyPolicy(policy);
+ assertNotNull("There was no response", result);
+ assertEquals("Unexpected result : " + result.getResult() + " - " + result.getComment(), "SAT", result.getResult());
+ assertEquals("Error report: " + result.getErrorMessage(), "", result.getErrorMessage());
+
+ System.out.println("Phase 3.2 - Traversal UNSAT.");
+ policy = ToscaPolicy.newBuilder().setIdTopologyTemplate(testTemplateId)
+ .setType(PolicyType.traversal).setSource("host2").setDestination("webserver1").setMiddlebox("fw").build();
+ result = client.verifyPolicy(policy);
+ assertNotNull("There was no response", result);
+ assertEquals("Unexpected result : " + result.getResult() + " - " + result.getComment(), "UNSAT", result.getResult());
+ assertEquals("Error report: " + result.getErrorMessage(), "", result.getErrorMessage());
+
+ Status resp = client.deleteTopologyTemplate(testTemplateId);
+ assertEquals("Error while deleting testTemplate", true, resp.getSuccess());
+
+ System.out.println("Test D completed.\n");
+ return;
+ }
+
+
+ @Test
+ public void test4Deletion() {
+ System.out.println("\nTest E: Deletion");
+ NewTopologyTemplate templ = client.createTopologyTemplate(testTemplate);
+
+ if(templ.getSuccess() != true) {
+ fail("Unable to create the graph.");
+ return;
+ }else {
+ Status resp = client.deleteTopologyTemplate(templ.getTopologyTemplate().getId());
+ assertEquals("Error while deleting testTemplate", true, resp.getSuccess());
+ }
+
+ System.out.println("Test E completed.\n");
+ return;
+ }
+
+
+ //Generates a correct instance of a TopologyTemplateGrpc to be used in tests
+ public void generateTestTemplate() {
+ TopologyTemplateGrpc.Builder templ = TopologyTemplateGrpc.newBuilder();
+ List<NodeTemplateGrpc> nodes = new ArrayList<NodeTemplateGrpc>();
+ List<RelationshipTemplateGrpc> relats = new ArrayList<RelationshipTemplateGrpc>();
+
+ //Definition of nodes
+ ToscaConfigurationGrpc node0conf = ToscaConfigurationGrpc.newBuilder().setDescription("node0configuration")
+ .setId("100").setConfiguration("[{\r\n\"webserver1\":\"host2\"\r\n}]").build();
+ NodeTemplateGrpc node0 = NodeTemplateGrpc.newBuilder().setConfiguration(node0conf).setId("100")
+ .setName("fw").setType(Type.firewall).build();
+ nodes.add(node0);
+
+ ToscaConfigurationGrpc node1conf = ToscaConfigurationGrpc.newBuilder().setDescription("node1configuration")
+ .setId("101").setConfiguration("[]").build();
+ NodeTemplateGrpc node1 = NodeTemplateGrpc.newBuilder().setConfiguration(node1conf).setId("101")
+ .setName("webserver1").setType(Type.webserver).build();
+ nodes.add(node1);
+
+ ToscaConfigurationGrpc node2conf = ToscaConfigurationGrpc.newBuilder().setDescription("node2configuration")
+ .setId("102").setConfiguration("[{\r\n\"protocol\":\"HTTP_REQUEST\",\r\n \"url\":\"www.facebook.com\"\r\n }]").build();
+ NodeTemplateGrpc node2 = NodeTemplateGrpc.newBuilder().setConfiguration(node2conf).setId("102")
+ .setName("host2").setType(Type.endhost).build();
+ nodes.add(node2);
+
+ ToscaConfigurationGrpc node3conf = ToscaConfigurationGrpc.newBuilder().setDescription("node3configuration")
+ .setId("103").setConfiguration("[ {\r\n\"protocol\":\"HTTP_REQUEST\",\r\n\"url\":\"www.google.com\",\r\n\"destination\":\"server1\"\r\n}]").build();
+ NodeTemplateGrpc node3 = NodeTemplateGrpc.newBuilder().setConfiguration(node3conf).setId("103")
+ .setName("host1").setType(Type.endhost).build();
+ nodes.add(node3);
+
+ ToscaConfigurationGrpc node4conf = ToscaConfigurationGrpc.newBuilder().setDescription("node4configuration")
+ .setId("104").setConfiguration("[\"host1\",\"host2\"]").build();
+ NodeTemplateGrpc node4 = NodeTemplateGrpc.newBuilder().setConfiguration(node4conf).setId("104")
+ .setName("antispamNode1").setType(Type.antispam).build();
+ nodes.add(node4);
+
+ //Building relationships
+ RelationshipTemplateGrpc rel0 = RelationshipTemplateGrpc.newBuilder().setId("1001")
+ .setIdSourceNodeTemplate("100").setIdTargetNodeTemplate("101").setName("fwToServ1").build();
+ relats.add(rel0);
+
+ RelationshipTemplateGrpc rel1 = RelationshipTemplateGrpc.newBuilder().setId("1002")
+ .setIdSourceNodeTemplate("101").setIdTargetNodeTemplate("100").setName("serv1ToFw").build();
+ relats.add(rel1);
+
+ RelationshipTemplateGrpc rel2 = RelationshipTemplateGrpc.newBuilder().setId("1003")
+ .setIdSourceNodeTemplate("100").setIdTargetNodeTemplate("103").setName("fwToHost1").build();
+ relats.add(rel2);
+
+ RelationshipTemplateGrpc rel3 = RelationshipTemplateGrpc.newBuilder().setId("1004")
+ .setIdSourceNodeTemplate("100").setIdTargetNodeTemplate("102").setName("fwToHost2").build();
+ relats.add(rel3);
+
+ RelationshipTemplateGrpc rel4 = RelationshipTemplateGrpc.newBuilder().setId("1005")
+ .setIdSourceNodeTemplate("102").setIdTargetNodeTemplate("100").setName("Host2Tofw").build();
+ relats.add(rel4);
+
+ RelationshipTemplateGrpc rel5 = RelationshipTemplateGrpc.newBuilder().setId("1006")
+ .setIdSourceNodeTemplate("103").setIdTargetNodeTemplate("100").setName("Host1Tofw").build();
+ relats.add(rel5);
+
+ this.testTemplate = templ.addAllNodeTemplate(nodes).addAllRelationshipTemplate(relats).setId("0").build();
+
+ TopologyTemplateGrpc.Builder templ2 = TopologyTemplateGrpc.newBuilder();
+ List<NodeTemplateGrpc> nodes2 = new ArrayList<NodeTemplateGrpc>();
+ List<RelationshipTemplateGrpc> relats2 = new ArrayList<RelationshipTemplateGrpc>();
+ nodes2.add(node0);
+ nodes2.add(node1);
+ nodes2.add(node2);
+ relats2.add(rel0);
+ relats2.add(rel1);
+ relats2.add(rel3);
+ relats2.add(rel4);
+
+ this.simpleTestTemplate = templ2.addAllNodeTemplate(nodes2).addAllRelationshipTemplate(relats2).setId("1").build();
+
+ }
+
+ /*class NodeTemplateGrpcComparator implements Comparator<NodeTemplateGrpc> {
+ public int compare(NodeTemplateGrpc n0, NodeTemplateGrpc n1) {
+ return n0.getName().compareTo(n1.getName());
+ }
+ }
+
+ class RelationshipTemplateGrpcComparator implements Comparator<RelationshipTemplateGrpc> {
+ public int compare(RelationshipTemplateGrpc n0, RelationshipTemplateGrpc n1) {
+ int source = n0.getIdSourceNodeTemplate().compareTo(n1.getIdSourceNodeTemplate());
+ int target = n0.getIdTargetNodeTemplate().compareTo(n1.getIdTargetNodeTemplate());
+ return source + target;
+ }
+ }*/
+
+}
diff --git a/verigraph/src/it/polito/verigraph/tosca/MappingUtils.java b/verigraph/src/it/polito/verigraph/tosca/MappingUtils.java new file mode 100644 index 0000000..a415ad2 --- /dev/null +++ b/verigraph/src/it/polito/verigraph/tosca/MappingUtils.java @@ -0,0 +1,215 @@ +/******************************************************************************* + * Copyright (c) 2018 Politecnico di Torino and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Apache License, Version 2.0 + * which accompanies this distribution, and is available at + * http://www.apache.org/licenses/LICENSE-2.0 + *******************************************************************************/ + +package it.polito.verigraph.tosca; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.InjectableValues; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.module.SimpleModule; + +import it.polito.tosca.jaxb.Definitions; +import it.polito.tosca.jaxb.TDocumentation; +import it.polito.tosca.jaxb.TServiceTemplate; +import it.polito.verigraph.grpc.ToscaConfigurationGrpc; +import it.polito.verigraph.model.Graph; +import it.polito.verigraph.model.Node; +import it.polito.verigraph.model.Test; +import it.polito.verigraph.model.Verification; +import it.polito.verigraph.tosca.converter.xml.GraphToXml; +import it.polito.verigraph.tosca.converter.yaml.GraphToYaml; +import it.polito.verigraph.tosca.deserializer.XmlConfigurationDeserializer; +import it.polito.verigraph.tosca.serializer.XmlConfigSerializer; +import it.polito.verigraph.tosca.yaml.beans.ServiceTemplateYaml; +import it.polito.verigraph.tosca.yaml.beans.VerificationYaml; + +public class MappingUtils { + + public static String prettyPrintJsonString(JsonNode jsonNode) { + try { + ObjectMapper mapper = new ObjectMapper(); + Object json = mapper.readValue(jsonNode.toString(), Object.class); + return System.getProperty("line.separator") + mapper.writerWithDefaultPrettyPrinter() + .writeValueAsString(json) + System.getProperty("line.separator"); + } catch (Exception e) { + return "Sorry, pretty print didn't work"; + } + } + + // From a list of nodes (path) returns a Definitions object that contains all the paths as different service templates + public static Definitions mapPathsToXml(List<List<Node>> paths) { + Definitions definitions = new Definitions(); + List<Graph> tempGraphs = new ArrayList<Graph>(); + + int i = 0; + for (List<Node> path: paths) { + Graph tempGraph = new Graph(); + tempGraph.setId(i++); + for (Node node : path) + tempGraph.getNodes().put(node.getId(), node); + tempGraphs.add(tempGraph); + } + + for (Graph g: tempGraphs) { + definitions.getServiceTemplateOrNodeTypeOrNodeTypeImplementation().add(GraphToXml.mapPathToXml(g)); + } + + return definitions; + } + + + // From a list of nodes (path) returns a list of ServiceTemplateYaml object that represent the paths + public static List<ServiceTemplateYaml> mapPathsToYaml(List<List<Node>> paths) { + List<ServiceTemplateYaml> serviceTemplates = new ArrayList<ServiceTemplateYaml>(); + List<Graph> tempGraphs = new ArrayList<Graph>(); + + int i = 0; + for (List<Node> path: paths) { + Graph tempGraph = new Graph(); + tempGraph.setId(i++); + for (Node node : path) + tempGraph.getNodes().put(node.getId(), node); + tempGraphs.add(tempGraph); + } + + for (Graph g: tempGraphs) { + serviceTemplates.add(GraphToYaml.mapGraphYaml(g)); + } + + return serviceTemplates; + } + + + public static Definitions mapVerificationToXml(Verification verification) { + Definitions toscaVerification = new Definitions(); + TDocumentation toscaVerificationResult = new TDocumentation(); + toscaVerificationResult.setSource(verification.getResult() + ": " + verification.getComment()); + toscaVerification.getDocumentation().add(toscaVerificationResult); + + List<TServiceTemplate> toscaPaths = new ArrayList<TServiceTemplate>(); + + int i = 0; + for (Test test: verification.getTests()) { + Graph tempGraph = new Graph(); + tempGraph.setId(i++); + for (Node node : test.getPath()) + tempGraph.getNodes().put(node.getId(), node); + + TServiceTemplate toscaPath = GraphToXml.mapPathToXml(tempGraph); + TDocumentation toscaTestResult = new TDocumentation(); + toscaTestResult.setSource(test.getResult()); + toscaPath.getDocumentation().add(toscaTestResult); + toscaPaths.add(toscaPath); + } + + toscaVerification.getServiceTemplateOrNodeTypeOrNodeTypeImplementation().addAll(0, toscaPaths); + return toscaVerification; + } + + + public static VerificationYaml mapVerificationToYaml(Verification verification) { + VerificationYaml verificationYaml = new VerificationYaml(); + verificationYaml.setResult(verification.getResult()); + verificationYaml.setComment(verification.getComment()); + + List<ServiceTemplateYaml> toscaPaths = new ArrayList<ServiceTemplateYaml>(); + + int i = 0; + for (Test test: verification.getTests()) { + Graph tempGraph = new Graph(); + tempGraph.setId(i++); + for (Node node : test.getPath()) + tempGraph.getNodes().put(node.getId(), node); + + ServiceTemplateYaml toscaPath = GraphToYaml.mapGraphYaml(tempGraph); + toscaPath.getMetadata().put("result", test.getResult()); + toscaPaths.add(toscaPath); + } + + verificationYaml.setPaths(toscaPaths); + return verificationYaml; + } + + + /** Return a string that represent the Tosca Configuration in json string. + * + * The string can be converted in JsonNode to be inserted in Model Configuration. + * + * Used for: xml-->model + * @throws JsonProcessingException*/ + public static String obtainStringConfiguration(it.polito.tosca.jaxb.Configuration nodeConfig) throws JsonProcessingException { + ObjectMapper mapper = new ObjectMapper(); + SimpleModule module = new SimpleModule(); + module.addSerializer(it.polito.tosca.jaxb.Configuration.class, new XmlConfigSerializer()); + mapper.registerModule(module); + + String stringConfiguration = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(nodeConfig); + if (stringConfiguration.equals("") || stringConfiguration == null) + return "[]"; + else + return stringConfiguration; + } + + + /** Return a Tosca Configuration with inside the representation of a model Configuration (only its JsonNode) + * + * Used for: model-->xml + * @throws JsonProcessingException */ + public static it.polito.tosca.jaxb.Configuration obtainToscaConfiguration(it.polito.verigraph.model.Configuration modelConfig, String type) throws JsonProcessingException { + + ObjectMapper mapper = new ObjectMapper(); + SimpleModule module = new SimpleModule(); + + //Passing the configuration type to the Deserializer context + module.addDeserializer(it.polito.tosca.jaxb.Configuration.class, new XmlConfigurationDeserializer()); + mapper.registerModule(module); + + it.polito.tosca.jaxb.Configuration toscaConfig = new it.polito.tosca.jaxb.Configuration(); + try { + toscaConfig = mapper.reader(new InjectableValues.Std().addValue("type", type)) + .forType(it.polito.tosca.jaxb.Configuration.class) + .readValue(modelConfig.getConfiguration()); + } catch (IOException e) { + //TODO shall we suppose that configuration stored on DB are always correct? + } + + return toscaConfig; + } + + /** Return a Tosca Configuration from a ConfigurationGrpc + * + * Used for: grpc-->xml + * @throws JsonProcessingException */ + public static it.polito.tosca.jaxb.Configuration obtainToscaConfiguration(ToscaConfigurationGrpc grpcConfig, String type) throws JsonProcessingException { + + ObjectMapper mapper = new ObjectMapper(); + SimpleModule module = new SimpleModule(); + + //Passing the configuration type to the Deserializer context + module.addDeserializer(it.polito.tosca.jaxb.Configuration.class, new XmlConfigurationDeserializer()); + mapper.registerModule(module); + + it.polito.tosca.jaxb.Configuration toscaConfig = new it.polito.tosca.jaxb.Configuration(); + try { + toscaConfig = mapper.reader(new InjectableValues.Std().addValue("type", type)) + .forType(it.polito.tosca.jaxb.Configuration.class) + .readValue(grpcConfig.getConfiguration()); + } catch (IOException e) { + //TODO shall we suppose that configuration stored on DB are always correct? + } + + return toscaConfig; + } + +} diff --git a/verigraph/src/it/polito/verigraph/tosca/README_CLI.txt b/verigraph/src/it/polito/verigraph/tosca/README_CLI.txt new file mode 100644 index 0000000..6ee1332 --- /dev/null +++ b/verigraph/src/it/polito/verigraph/tosca/README_CLI.txt @@ -0,0 +1,66 @@ +** Verigraph Verification Service - Command Line Interface ** + +The CLI allows to interact with the Verigraph Verification Service using both the RESTful and gRPC interface. +The CLI allows CRUD operations on graphs and three kind of verification. + + +-- Available commands -- +> CONFIGURE -use <Interface> -format <contentFormat> -port <servicePort> -host <hostname> +> HELP +> EXIT +> GETALL +> GET <graphId> +> CREATE <validFilePath> +> UPDATE <graphId> <validFilePath> +> DELETE <graphId> +> VERIFY <graphId> <verificationType> <sourceNode> <destinationNode> [ <middleboxNode> ] + + +-- CLI commands -- +> CONFIGURE -use <Interface> -format <contentFormat> +Allows to configure connection parameters (host and port ), the interface (REST or gRPC ) and the data format +(JSON, XML or YAML ) to be used to communicate with the verification service, XML and YAML formats exploit an extension +of TOSCA specification. At program start the default configuration uses the REST interface with XML data format. +Note that the JSON format is not supported by the grpc interface. + +> HELP +Prints on screen the CLI documentation. + +> EXIT +Closes REST/gRPC client and exits. + + +-- CRUD on graphs -- +> GETALL +Performs a request without specifying a particular graph id. The service will return +a list of graph templates in the currently selected format and will print them on screen. + +> GET <graphId> +Performs a request for a specific graph whose id MUST be specified as a long integer +value. If present the graph will be returned and printed on screen in the currently selected format. + +> CREATE <validFilePath> +Performs a create graph request providing a graph template as a file. +The <validFilePath> must point to an existing file whose filenme must be coherent with the currently selected +data format. The server can accept or not the provided graph upon its validation against Tosca Verigraph specification +for XML/YAML or against Verigraph JSON schema. For further info see Verigraph Service documentation at [...]. + +> UPDATE <graphId> <validFilePath> +Performs an update request for a specific graph providing a graph template as a file. +The provided filename must be coherent with the currently selected data format and the <LongId> must be a long integer +corresponding to one of the graphs previously created. The server can accept or not the provided graph upon its +validation against Tosca Verigraph specification for XML/YAML or against Verigraph JSON schema. +For further info see Verigraph Service documentation at [...]. + +> DELETE <graphId> +Performs a delete request for a specific graph. +The provided id must be a long integer corresponding to a previously created graph. + + +-- Verification -- +> VERIFY <graphId> <verificationType> <sourceNode> <destinationNode> [ <middleboxNode> ] +Performs a verification request for a specific graph. +The <graphId> must be the long integer id of a previously created graph. Three types of verification services are +available: reachability, isolation and traversal. The source, destination and middlebox node parameters +must be provided as string and must correspond to the name of a Node in the specified graph. The middlebox parameter +must not be provided in case of reachability verification.
\ No newline at end of file diff --git a/verigraph/src/it/polito/verigraph/tosca/ToscaCLI.java b/verigraph/src/it/polito/verigraph/tosca/ToscaCLI.java new file mode 100644 index 0000000..c9f01c2 --- /dev/null +++ b/verigraph/src/it/polito/verigraph/tosca/ToscaCLI.java @@ -0,0 +1,1055 @@ +/*******************************************************************************
+ * Copyright (c) 2018 Politecnico di Torino and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Apache License, Version 2.0
+ * which accompanies this distribution, and is available at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+
+package it.polito.verigraph.tosca;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.NoSuchElementException;
+import java.util.Scanner;
+import java.util.regex.Pattern;
+
+import javax.ws.rs.ProcessingException;
+import javax.ws.rs.client.Client;
+import javax.ws.rs.client.ClientBuilder;
+import javax.ws.rs.client.Entity;
+import javax.ws.rs.client.Invocation.Builder;
+import javax.ws.rs.client.WebTarget;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Marshaller;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Source;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.stream.StreamResult;
+import javax.xml.transform.stream.StreamSource;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.dataformat.yaml.YAMLMapper;
+import com.sun.research.ws.wadl.ObjectFactory;
+
+import it.polito.tosca.jaxb.Configuration;
+import it.polito.tosca.jaxb.Definitions;
+import it.polito.tosca.jaxb.TDefinitions;
+import it.polito.verigraph.grpc.GraphGrpc;
+import it.polito.verigraph.grpc.TopologyTemplateGrpc;
+import it.polito.verigraph.grpc.ToscaPolicy;
+import it.polito.verigraph.grpc.client.ToscaClient;
+import it.polito.verigraph.grpc.server.GrpcUtils;
+import it.polito.verigraph.model.Graph;
+import it.polito.verigraph.tosca.converter.grpc.GraphToGrpc;
+import it.polito.verigraph.tosca.converter.grpc.GrpcToGraph;
+import it.polito.verigraph.tosca.converter.grpc.GrpcToXml;
+import it.polito.verigraph.tosca.converter.grpc.GrpcToYaml;
+import it.polito.verigraph.tosca.converter.grpc.XmlToGrpc;
+import it.polito.verigraph.tosca.converter.grpc.YamlToGrpc;
+import it.polito.verigraph.tosca.yaml.beans.ServiceTemplateYaml;
+
+
+public class ToscaCLI {
+
+ private static final String helper = "./README_CLI.txt";
+
+ //Service parameters.
+ private String host;
+ private int port;
+
+ //New media type for yaml rest request
+ private static final MediaType yamlMedia = new MediaType("application", "x-yaml");
+ private static final String defaultHost = "localhost";
+ private static final int defaultRestPort = 8080;
+ private static final int defaultGrpcPort = 50051;
+
+ //Input validation patterns
+ private static final Pattern yamlSource = Pattern.compile(".*\\.yaml$");
+ private static final Pattern xmlSource = Pattern.compile(".*\\.xml");
+ private static final Pattern jsonSource = Pattern.compile(".*\\.json$");
+ private static final Pattern configOpt = Pattern.compile("-use|-format|-port|-host", Pattern.CASE_INSENSITIVE);
+ private static final Pattern useOpt = Pattern.compile("grpc|rest", Pattern.CASE_INSENSITIVE);
+ private static final Pattern formatOpt = Pattern.compile("yaml|json|xml", Pattern.CASE_INSENSITIVE);
+ private static final Pattern policies = Pattern.compile("reachability|isolation|traversal", Pattern.CASE_INSENSITIVE);
+
+ //Configuration parameters
+ private Boolean useRest;
+ private String mediatype;
+ private Client restClient;
+ private ToscaClient grpcClient;
+
+ public ToscaCLI(){
+ //Variables representing the client environment
+ this.useRest = true;
+ this.port = defaultRestPort;
+ this.host = defaultHost;
+ this.mediatype = MediaType.APPLICATION_XML;
+ this.restClient = null;
+ this.grpcClient = null;
+ }
+
+
+ public static void main(String[] args) {
+ ToscaCLI myclient = new ToscaCLI();
+ try {
+ myclient.clientStart();
+ } catch (Exception e) {
+ System.out.println("-- Unexpected error, service closing.");
+ }
+ return;
+ }
+
+ //Build base Uri for REST service
+ private String buildBaseUri() {
+ return "http://" + this.host + ":" + String.valueOf(this.port) + "/verigraph/api/graphs";
+ }
+
+ //Function iterating getting user commands.
+ public void clientStart(){
+ System.out.println("++ Welcome to Verigraph Verification Service...");
+ System.out.println("++ Type HELP for instructions on client use...");
+
+ Scanner reader = null;
+ InputStream input = System.in;
+ Scanner scan = new Scanner(System.in);
+ String commandline;
+
+ while(true) {
+ System.out.print("++ Please insert command : ");
+ try{
+
+ while(input.available()!=0) input.skip(input.available());
+ commandline = scan.nextLine();
+ reader = new Scanner(commandline);
+
+ switch (reader.next().toUpperCase()) {
+ case "GETALL":
+ if(useRest) this.restGetAll(reader);
+ else this.grpcGetAll(reader);
+ break;
+ case "GET":
+ if(useRest) this.restGet(reader);
+ else this.grpcGet(reader);
+ break;
+ case "CREATE":
+ if(useRest) this.restCreate(reader);
+ else this.grpcCreate(reader);
+ break;
+ case "DELETE":
+ if(useRest) this.restDelete(reader);
+ else grpcDelete(reader);
+ break;
+ case "UPDATE":
+ if(useRest) this.restUpdate(reader);
+ else this.grpcUpdate(reader);
+ break;
+ case "VERIFY":
+ if(useRest) this.restVerify(reader);
+ else this.grpcVerify(reader);
+ break;
+ case "HELP":
+ this.printHelper();
+ break;
+ case "CONFIGURE":
+ this.setConfig(reader);
+ break;
+ case "EXIT":
+ System.out.println("++ Client closing...");
+ scan.close();
+ input.close();
+ reader.close();
+ if(grpcClient != null) this.grpcClient.shutdown();
+ if(restClient != null) this.restClient.close();
+ System.out.println("++ Goodbye!");
+ System.exit(0);
+ break;
+ default:
+ System.out.println("-- Unknown or bad formed command, type HELP to show commands documentation.");
+ break;
+ }
+
+ }catch(NoSuchElementException ex) {
+ System.err.println("-- Unrecognized or incorrect command,"
+ + " type help to know how to use the client...");
+ continue;
+ }catch(IOException | InterruptedException ex){
+ handleError(ex);
+ }finally {
+ reader.close();
+ }
+ }
+
+ }
+
+
+ public void printHelper() {
+ Scanner filereader = null;
+ try {
+ File inputfile = new File(helper);
+ filereader = new Scanner(inputfile).useDelimiter("\\Z");
+ String content = filereader.next();
+ if (filereader.ioException() != null) {
+ throw new IOException(filereader.ioException());
+ }
+ if(content != null) System.out.println(content);
+ } catch (IOException e) {
+ handleError(e);
+ }finally {
+ if(filereader != null) filereader.close();
+ }
+
+ }
+
+ public void setConfig(Scanner reader) throws InterruptedException {
+ if(!reader.hasNext(configOpt)) {
+ System.out.println("-- No or bad formed configuration options provided.");
+ return;
+ }
+ while(reader.hasNext(configOpt)) {
+ switch(reader.next().toLowerCase()) {
+ case "-use":
+ if(reader.hasNext(useOpt)) {
+ if(reader.next().toLowerCase().equals("rest")) {
+ if(grpcClient != null) {
+ grpcClient.shutdown();
+ grpcClient = null;
+ }
+ this.port = defaultRestPort;
+ restClient = ClientBuilder.newClient();
+ useRest = true;
+ }
+ else {
+ if(restClient != null) {
+ restClient.close();
+ restClient = null;
+ }
+ this.port = defaultGrpcPort;
+ grpcClient = new ToscaClient(host, port);
+ useRest = false;
+ }
+ }else {
+ System.out.println("-- Unrecognized values for option -use, accepted values are: rest, grpc.");
+ }
+ break;
+ case "-format":
+ if(reader.hasNext(formatOpt)) {
+ String command = reader.next();
+ if(command.toLowerCase().equals("json")) mediatype = MediaType.APPLICATION_JSON;
+ else if(command.toLowerCase().equals("xml")) mediatype = MediaType.APPLICATION_XML;
+ else if(command.toLowerCase().equals("yaml")) mediatype = "application/x-yaml";
+ }else {
+ System.out.println("-- Unrecognized values for option -format, accepted formats are: json, xml, yaml.");
+ }
+ break;
+ case "-host":
+ if(reader.hasNext()) {
+ this.host = reader.next();
+ if(grpcClient != null) {
+ grpcClient.shutdown();
+ grpcClient = new ToscaClient(host, port);
+ System.out.println("++ Host configuration changed restarting grpc client...");
+ }
+ }
+ else {
+ System.out.println("-- Provide a valid hostname.");
+ }
+ break;
+ case "-port":
+ if(reader.hasNextInt()) {
+ int newvalue = reader.nextInt();
+ if(0 > newvalue || 65535 < newvalue) {
+ System.out.println("-- The provided port number is not valid, port has not been modified.");
+ }else {
+ this.port = newvalue;
+ if(grpcClient != null) {
+ grpcClient.shutdown();
+ grpcClient = new ToscaClient(host, port);
+ System.out.println("++ Port configuration changed restarting grpc client...");
+ }
+ }
+ }
+ else {
+ System.out.println("-- Provide a port as an integer.");
+ }
+ break;
+ default:
+ System.out.println("-- Unrecognized option!");
+ }
+ }
+
+ }
+
+ //Utility function used only to print exception message
+ public void handleError(Exception e) {
+ String errMsg = e.getMessage();
+ if(errMsg == null) {
+ System.out.println("-- Error: unexpected error occurred.");
+ }else {
+ System.out.println("-- Error: " + errMsg);
+ }
+ return;
+ }
+
+
+ // RESTful service interface CRUD and Verify functions
+ public void restGetAll(Scanner reader) {
+ try {
+ // Build a new client if it does not exist
+ if (restClient == null)
+ restClient = ClientBuilder.newClient();
+
+ // targeting the graphs resource
+ WebTarget target = restClient.target(this.buildBaseUri());
+
+ // Performing the request and reading the response
+ Response res = target.request(mediatype).get();
+ this.readResponseRest("GETALL", res);
+
+ }catch(ProcessingException e) {
+ System.out.println("-- Error: the provided host address is not valid.");
+ }catch (Exception e) {
+ handleError(e);
+ }
+ return;
+ }
+
+
+ public void restGet(Scanner reader) {
+
+ try {
+ // Build a new client if it does not exist
+ if (restClient == null)
+ restClient = ClientBuilder.newClient();
+
+ if (!reader.hasNextLong()) {
+ System.out.println("-- Provide the integer Id for the requested graph.");
+ return;
+ }
+
+ // Targeting the specified graph resource
+ WebTarget target = restClient.target(this.buildBaseUri() + "/" + String.valueOf(reader.nextLong()));
+
+ // Performing the request and reading the response
+ Response res = target.request(mediatype).get();
+ this.readResponseRest("GET", res);
+
+ }catch(ProcessingException e) {
+ System.out.println("-- Error: the provided host address is not valid.");
+ } catch (Exception e) {
+ handleError(e);
+ }
+
+ }
+
+
+
+ public void restCreate(Scanner reader) {
+
+ try {
+ // Getting file content
+ String content = readFile(reader);
+ if (content == null) {
+ System.out.println("-- The required operation can't be performed.");
+ return;
+ }
+
+ // Build a new client if it does not exist
+ if (restClient == null)
+ restClient = ClientBuilder.newClient();
+
+ // Targeting the resource
+ WebTarget target = restClient.target(this.buildBaseUri());
+
+ // Performing the request and reading the response
+ Builder mypost = target.request(mediatype);
+ Response res = null;
+ switch (mediatype) {
+ case MediaType.APPLICATION_JSON:
+ res = mypost.post(Entity.json(content));
+ break;
+ case MediaType.APPLICATION_XML:
+ res = mypost.post(Entity.xml(content));
+ break;
+ case "application/x-yaml":
+ res = mypost.post(Entity.entity(content, yamlMedia));
+ break;
+ }
+
+ this.readResponseRest("CREATE", res);
+ }catch(ProcessingException e) {
+ System.out.println("-- Error: the provided host address is not valid.");
+ } catch (Exception e) {
+ handleError(e);
+ }
+
+ return;
+ }
+
+
+
+ public void restDelete(Scanner reader) {
+ try {
+ // Build a new client if it does not exist
+ if (restClient == null)
+ restClient = ClientBuilder.newClient();
+
+ if (!reader.hasNextLong()) {
+ System.out.println("-- Provide the integer Id of the graph you want to delete.");
+ return;
+ }
+
+ // Targeting the specified graph resource
+ WebTarget target = restClient.target(this.buildBaseUri() + "/" + String.valueOf(reader.nextLong()));
+
+ // Performing the request and reading the response
+ Response res = target.request(mediatype).delete();
+ this.readResponseRest("DELETE", res);
+ }catch(ProcessingException e) {
+ System.out.println("-- Error: the provided host address is not valid.");
+ } catch (Exception e) {
+ handleError(e);
+ }
+
+ return;
+ }
+
+
+ public void restUpdate(Scanner reader) {
+ try {
+
+ //Getting the target graph
+ if(!reader.hasNextLong()) {
+ System.out.println("-- Please provide a valid id for the graph to be update");
+ return;
+ }
+
+ // Build a new client if it does not exist
+ if (restClient == null)
+ restClient = ClientBuilder.newClient();
+
+ // Targeting the resource
+ WebTarget target = restClient.target(this.buildBaseUri() + "/" + reader.next());
+
+ // Getting file content
+ String content = readFile(reader);
+ if (content == null) {
+ System.out.println("-- The required operation can't be performed.");
+ return;
+ }
+
+ // Performing the request and reading the resonse
+ Builder myupdate = target.request(mediatype);
+ Response res = null;
+ switch (mediatype) {
+ case MediaType.APPLICATION_JSON:
+ res = myupdate.put(Entity.json(content));
+ break;
+ case MediaType.APPLICATION_XML:
+ res = myupdate.put(Entity.xml(content));
+ break;
+ case "application/x-yaml":
+ res = myupdate.put(Entity.entity(content, yamlMedia));
+ break;
+ }
+
+ this.readResponseRest("UPDATE", res);
+
+ }catch(ProcessingException e) {
+ System.out.println("-- Error: the provided host address is not valid.");
+ } catch (Exception e) {
+ handleError(e);
+ }
+
+ }
+
+
+ public void restVerify(Scanner reader) {
+ String whichpolicy = null;
+ String graphId, source, destination, middlebox = null;
+
+ try {
+ if(!reader.hasNextLong()) {
+ System.out.println("-- Provide the graph on which you want to perform verification.");
+ return;
+ }
+ graphId = reader.next();
+
+ if (!reader.hasNext(policies)) {
+ System.out.println("-- Provide the requested type of verfication.");
+ return;
+ }
+ whichpolicy = reader.next().toLowerCase();
+
+ try {
+ source = reader.next();
+ destination = reader.next();
+ if(!whichpolicy.equals("reachability")) {
+ middlebox = reader.next();
+ }
+ }catch(NoSuchElementException ex) {
+ System.out.println("-- Wrong or missing verification parameters.");
+ return;
+ }
+
+ // Build a new client if it does not exist
+ if (restClient == null)
+ restClient = ClientBuilder.newClient();
+
+ // Targeting the resource
+ WebTarget target = restClient.target(this.buildBaseUri() + "/" + graphId + "/policy")
+ .queryParam("source", source)
+ .queryParam("destination", destination)
+ .queryParam("type", whichpolicy);
+ if(!whichpolicy.equals("reachability")) {
+ target = target.queryParam("middlebox", middlebox);
+ }
+
+ Response res = target.request(mediatype).get();
+ this.readResponseRest("VERIFY", res);
+ }catch(ProcessingException e) {
+ System.out.println("-- Error: the provided host address is not valid.");
+ } catch (Exception e) {
+ handleError(e);
+ }
+
+ }
+
+ //gRPC service interface CRUD and Verify functions
+ public void grpcGetAll(Scanner reader) {
+
+ try {
+ if(grpcClient == null)
+ grpcClient = new ToscaClient(host, port);
+
+ //Added for backward compatibility with JSON grpc
+ if(mediatype == MediaType.APPLICATION_JSON) {
+ List<GraphGrpc> receivedGraphsGrpc = grpcClient.getGraphs();
+
+ if(receivedGraphsGrpc == null) {
+ System.out.println("-- GET Failed : was not possible to perform the required operations.");
+ return;
+ }
+ else if(receivedGraphsGrpc.isEmpty()) {
+ System.out.println("++ GET Success no graph was returned.");
+ return;
+ }
+
+ List<Graph> receivedGraphs = new ArrayList<Graph>();
+ for(GraphGrpc curr : receivedGraphsGrpc) {
+ receivedGraphs.add(GrpcUtils.deriveGraph(curr));
+ }
+ this.marshallToJson(receivedGraphs);
+ return;
+ }
+
+ //Code for the Tosca compliant implementation
+ List<TopologyTemplateGrpc> templates;
+ templates = grpcClient.getTopologyTemplates();
+
+ if(templates == null) {
+ System.out.println("-- GET Failed : was not possible to perform the required operations.");
+ return;
+ }
+ else if(templates.isEmpty()) {
+ System.out.println("++ GET Success no graph was returned.");
+ return;
+ }
+
+ switch(mediatype) {
+ case MediaType.APPLICATION_XML:
+ List<Definitions> receivedDefs = new ArrayList<Definitions>();
+ for(TopologyTemplateGrpc curr : templates) {
+ receivedDefs.add(GrpcToXml.mapGraph(curr));
+ }
+ this.marshallToXml(receivedDefs);
+ break;
+
+ case "application/x-yaml":
+ List<ServiceTemplateYaml> receivedTempls = new ArrayList<ServiceTemplateYaml>();
+ for(TopologyTemplateGrpc curr : templates) {
+ receivedTempls.add(GrpcToYaml.mapGraphYaml(curr));
+ }
+ this.marshallToYaml(receivedTempls);
+ break;
+
+ }
+ } catch (Exception e) {
+ handleError(e);
+ }
+
+ }
+
+
+ public void grpcGet(Scanner reader) {
+
+ try {
+ if (grpcClient == null)
+ grpcClient = new ToscaClient(host, port);
+
+ if (!reader.hasNextLong()) {
+ System.out.println("-- Provide the integer Id for the requested graph.");
+ return;
+ }
+
+ //Added for backward compatibility with JSON grpc
+ if(mediatype == MediaType.APPLICATION_JSON) {
+ GraphGrpc graph = grpcClient.getGraph(reader.nextLong());
+ if(graph == null || !graph.getErrorMessage().equals(""));
+ List<Graph> receivedGraphs = new ArrayList<Graph>();
+ receivedGraphs.add(GrpcUtils.deriveGraph(graph));
+ this.marshallToJson(receivedGraphs);
+ return;
+ }
+
+ //Code for Tosca compliant implementation
+ TopologyTemplateGrpc templ = grpcClient.getTopologyTemplate(reader.next());
+ if(templ == null || !templ.getErrorMessage().equals("")) {
+ return;
+ }
+ switch(mediatype) {
+ // case MediaType.APPLICATION_JSON:
+ // Graph obt = GrpcToGraph.deriveGraph(templ);
+ // List<Graph> list = new ArrayList<Graph>();
+ // list.add(obt);
+ // marshallToJson(list);
+ // break;
+ case MediaType.APPLICATION_XML:
+ List<Definitions> receivedDefs = new ArrayList<Definitions>();
+ receivedDefs.add(GrpcToXml.mapGraph(templ));
+ this.marshallToXml(receivedDefs);
+ break;
+
+ case "application/x-yaml":
+ List<ServiceTemplateYaml> receivedTempls = new ArrayList<ServiceTemplateYaml>();
+ receivedTempls.add(GrpcToYaml.mapGraphYaml(templ));
+ this.marshallToYaml(receivedTempls);
+ break;
+ }
+
+ } catch (Exception e) {
+ handleError(e);
+ }
+ }
+
+ public void grpcCreate(Scanner reader) {
+ try {
+ if (grpcClient == null)
+ grpcClient = new ToscaClient(host, port);
+
+ switch (mediatype) {
+ case MediaType.APPLICATION_JSON:
+ if(reader.hasNext(jsonSource)) {
+ ObjectMapper mapper = new ObjectMapper();
+ Graph modelGraph = mapper.readValue(readFile(reader), Graph.class);
+ GraphGrpc graph = GrpcUtils.obtainGraph(modelGraph);
+ grpcClient.createGraph(graph);
+ }else {
+ System.out.println("-- The provided file is not compatible with the current configuration [json].");
+ return;
+ }
+ break;
+ case MediaType.APPLICATION_XML:
+ if (reader.hasNext(xmlSource)) {
+ grpcClient.createTopologyTemplate(XmlToGrpc.obtainTopologyTemplateGrpc(reader.next()));
+ } else {
+ System.out.println("-- The provided file is not compatible with the current configuration [xml].");
+ return;
+ }
+ break;
+
+ case "application/x-yaml":
+ if (reader.hasNext(yamlSource)) {
+ grpcClient.createTopologyTemplate(YamlToGrpc.obtainTopologyTemplateGrpc(reader.next()));
+ } else {
+ System.out.println("-- The provided file is not compatible with the current configuration [yaml].");
+ return;
+ }
+ break;
+ }
+
+ } catch (JAXBException je) {
+ System.out.println("-- Error while parsing xml : " + je.getMessage());
+ } catch (IOException ie) {
+ System.out.println("-- Error reading the file : " + ie.getMessage());
+ } catch(Exception e) {
+ handleError(e);
+ }
+
+ return;
+ }
+
+
+ public void grpcDelete(Scanner reader) {
+
+ try {
+ if (grpcClient == null)
+ grpcClient = new ToscaClient(host, port);
+
+ if (!reader.hasNextLong()) {
+ System.out.println("-- Provide the integer Id of the graph you want to delete.");
+ return;
+ }
+
+ grpcClient.deleteTopologyTemplate(reader.next());
+
+ } catch (Exception e) {
+ handleError(e);
+ }
+
+ return;
+ }
+
+
+ public void grpcUpdate(Scanner reader) {
+ try {
+ if (grpcClient == null)
+ grpcClient = new ToscaClient(host, port);
+
+ //Checking if user ha provided the id of the graph to be updated and retrieving it
+ if(!reader.hasNextLong()) {
+ System.out.println("-- Please provide a valid id for the graph to be update");
+ return;
+ }
+ String id = reader.next();
+
+ //Reading the file and performing the request according to current configuration
+ switch (mediatype) {
+ case MediaType.APPLICATION_JSON:
+ if(reader.hasNext(jsonSource)) {
+ ObjectMapper mapper = new ObjectMapper();
+ Graph modelGraph = mapper.readValue(readFile(reader), Graph.class);
+ GraphGrpc graph = GrpcUtils.obtainGraph(modelGraph);
+ grpcClient.updateGraph(new Long(id), graph);
+ }else {
+ System.out.println("-- The provided file is not compatible with the current configuration [json].");
+ return;
+ }
+ break;
+ case MediaType.APPLICATION_XML:
+ if (reader.hasNext(xmlSource)) {
+ grpcClient.updateTopologyTemplate(XmlToGrpc.obtainTopologyTemplateGrpc(reader.next()), id);
+ } else {
+ System.out.println("-- The provided file is not compatible with the current configuration.");
+ return;
+ }
+ break;
+
+ case "application/x-yaml":
+ if (reader.hasNext(yamlSource)) {
+ grpcClient.updateTopologyTemplate(YamlToGrpc.obtainTopologyTemplateGrpc(reader.next()), id);
+ } else {
+ System.out.println("-- The provided file is not compatible with the current configuration.");
+ return;
+ }
+ break;
+ }
+ } catch (JAXBException je) {
+ System.out.println("-- Error while parsing xml : " + je.getMessage());
+ } catch (IOException ie) {
+ System.out.println("-- Error reading the file : " + ie.getMessage());
+ } catch(Exception e) {
+ handleError(e);
+ }
+ }
+
+
+ public void grpcVerify(Scanner reader) {
+ ToscaPolicy.Builder policyBuilder = ToscaPolicy.newBuilder();
+ String graphId, whichPolicy, source, destination, middlebox = null;
+
+ try {
+ if(!reader.hasNextLong()) {
+ System.out.println("-- Provide the graph on which you want to perform verification.");
+ return;
+ }
+ graphId = reader.next();
+
+ if (!reader.hasNext(policies)) {
+ System.out.println("-- Provide the requested type of verfication.");
+ return;
+ }
+ whichPolicy = reader.next().toLowerCase();
+
+ try {
+ source = reader.next();
+ destination = reader.next();
+ if(!whichPolicy.equals("reachability")) {
+ middlebox = reader.next();
+ }
+ }catch(NoSuchElementException ex) {
+ System.out.println("-- Wrong or missing verification parameters.");
+ return;
+ }
+
+ policyBuilder.setIdTopologyTemplate(graphId);
+ policyBuilder.setDestination(destination);
+ policyBuilder.setSource(source);
+ switch(whichPolicy) {
+ case "reachability":
+ policyBuilder.setType(ToscaPolicy.PolicyType.forNumber(0));
+ break;
+ case "isolation":
+ policyBuilder.setType(ToscaPolicy.PolicyType.forNumber(1));
+ policyBuilder.setMiddlebox(middlebox);
+ break;
+ case "traversal":
+ policyBuilder.setType(ToscaPolicy.PolicyType.forNumber(2));
+ policyBuilder.setMiddlebox(middlebox);
+ break;
+ }
+
+ if (grpcClient == null)
+ grpcClient = new ToscaClient(host, port);
+
+ //Sending verification request
+ grpcClient.verifyPolicy(policyBuilder.build());
+
+ } catch (Exception e) {
+ handleError(e);
+ }
+
+ return;
+ }
+
+
+ public void readResponseRest(String responseOf, Response res) {
+ switch(responseOf) {
+ case "GETALL":
+ switch (res.getStatus()) {
+ case 200:
+ System.out.println("++ GET success :");
+ break;
+ case 500:
+ System.out.println("-- GET failed : internal server error.");
+ break;
+ default:
+ System.out.println("** Unexpected response");
+ break;
+ }
+ break;
+
+ case "GET":
+ switch (res.getStatus()) {
+ case 200:
+ System.out.println("++ GET success :");
+ break;
+ case 404:
+ System.out.println("-- GET failed : graph not found.");
+ break;
+ case 500:
+ System.out.println("-- GET failed : internal server error.");
+ break;
+ default:
+ System.out.println("** Unexpected response **");
+ break;
+ }
+ break;
+
+ case "CREATE":
+ switch (res.getStatus()) {
+ case 201:
+ System.out.println("++ POST success : graph created.");
+ break;
+ case 400:
+ System.out.println("-- POST failed : bad request.");
+ break;
+ case 500:
+ System.out.println("-- POST failed : internal server error.");
+ break;
+ default:
+ System.out.println("** Unexpected response **");
+ break;
+ }
+ break;
+ case "DELETE":
+ switch (res.getStatus()) {
+ case 204:
+ System.out.println("++ DELETE success : graph deleted.");
+ break;
+ case 403:
+ System.out.println("-- DELETE failed : invalid graph ID.");
+ break;
+ case 404:
+ System.out.println("-- DELETE failed : invalid graph id.");
+ break;
+ case 500:
+ System.out.println("-- DELETE failed : internal server error.");
+ break;
+ default:
+ System.out.println("** Unexpected response **");
+ break;
+ }
+ break;
+ case "UPDATE":
+ switch (res.getStatus()) {
+ case 200:
+ System.out.println("++ PUT success : graph correctly updated.");
+ break;
+ case 400:
+ System.out.println("-- PUT failed : invalid graph object.");
+ break;
+ case 403:
+ System.out.println("-- PUT failed : invalid graph ID.");
+ break;
+ case 404:
+ System.out.println("-- PUT failed : graph not found.");
+ break;
+ case 500:
+ System.out.println("-- PUT failed : internal server error.");
+ break;
+ default:
+ System.out.println("** Unexpected response **");
+ break;
+ }
+ break;
+
+ default:
+
+ }
+
+ //In case of errors we do not read the message body
+ if(res.hasEntity() && res.getStatus() <= 300) {
+ String responseBody = prettyFormat(res.readEntity(String.class));
+ if(responseBody != null) System.out.println(responseBody);
+ }
+ else {
+ System.out.println("++ No content in the message body");
+ }
+
+ return;
+ }
+
+
+ public void marshallToXml(List<Definitions> defs) {
+ try {
+ JAXBContext jc = JAXBContext.newInstance(ObjectFactory.class, TDefinitions.class, Configuration.class);
+ Marshaller m = jc.createMarshaller();
+ m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
+ for (Definitions def : defs) {
+ // To be tested, in case of problems def must be converted to a JAXBElement
+ m.marshal(def, System.out);
+ System.out.println("\n");
+ }
+
+ } catch (JAXBException je) {
+ System.out.println("-- Error while marshalling : " + je.getMessage());
+ }
+ return;
+ }
+
+ public void marshallToYaml(List<ServiceTemplateYaml> templates) {
+ try {
+ YAMLMapper mapper = new YAMLMapper();
+ mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
+ for (ServiceTemplateYaml templ : templates) {
+ System.out.println(mapper.writerWithDefaultPrettyPrinter().writeValueAsString(templ));
+ System.out.println("\n");
+ }
+
+ } catch (JsonProcessingException je) {
+ System.out.println("-- Error while marshalling : " + je.getMessage());
+
+ }
+ return;
+ }
+
+ public void marshallToJson(List<Graph> templates) {
+ try {
+ ObjectMapper mapper = new ObjectMapper();
+ //mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
+ for (Graph templ : templates) {
+ System.out.println(mapper.writerWithDefaultPrettyPrinter().writeValueAsString(templ));
+ System.out.println("\n");
+ }
+
+ } catch (JsonProcessingException je) {
+ System.out.println("-- Error while marshalling : " + je.getMessage());
+
+ }
+ return;
+ }
+
+
+ // Reads the whole file into a string and performs a minimum validation on file type
+ public String readFile(Scanner reader) {
+
+ String content = null;
+ Scanner filereader = null;
+ if ((mediatype.equals("application/x-yaml") && reader.hasNext(yamlSource))
+ || (mediatype.equals(MediaType.APPLICATION_XML) && reader.hasNext(xmlSource))
+ || (mediatype.equals(MediaType.APPLICATION_JSON) && reader.hasNext(jsonSource))) {
+ try {
+ File inputfile = new File(reader.next());
+ filereader = new Scanner(inputfile).useDelimiter("\\Z");
+ content = filereader.next();
+ if (filereader.ioException() != null) {
+ throw new IOException(filereader.ioException());
+ } else {
+ System.out.println("++ File correctly read.");
+ }
+ } catch (FileNotFoundException ex) {
+ System.out.println("-- Error : the provided file does not exist!");
+ }catch (IOException ex) {
+ System.out.println("-- Error : an error occurred reading the input file!");
+ }catch (Exception e) {
+ handleError(e);
+ }finally {
+ if(filereader != null) filereader.close();
+ }
+
+ } else {
+ System.out.println("-- Error : the file provided in input does not match with the current client configuration.");
+ }
+
+ return content;
+ }
+
+
+ public String prettyFormat(String input) {
+ String formattedString = null;
+
+ try {
+ switch(mediatype) {
+ case MediaType.APPLICATION_XML:
+ Source xmlInput = new StreamSource(new StringReader(input));
+ StringWriter stringWriter = new StringWriter();
+ StreamResult xmlOutput = new StreamResult(stringWriter);
+ TransformerFactory transformerFactory = TransformerFactory.newInstance();
+ transformerFactory.setAttribute("indent-number", 2);
+ Transformer transformer = transformerFactory.newTransformer();
+ transformer.setOutputProperty(OutputKeys.INDENT, "yes");
+ transformer.transform(xmlInput, xmlOutput);
+ formattedString = xmlOutput.getWriter().toString();
+ break;
+ case MediaType.APPLICATION_JSON:
+ ObjectMapper mapper = new ObjectMapper();
+ Object jsonObj = mapper.readValue(input, Object.class);
+ formattedString = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(jsonObj);
+ break;
+ case "application/x-yaml":
+ formattedString = input;
+ break;
+ }
+ } catch (Exception e) {
+ formattedString = e.getCause().toString();
+ }
+
+ return formattedString;
+ }
+
+
+}
diff --git a/verigraph/src/it/polito/verigraph/tosca/XmlParsingUtils.java b/verigraph/src/it/polito/verigraph/tosca/XmlParsingUtils.java new file mode 100644 index 0000000..5830bf8 --- /dev/null +++ b/verigraph/src/it/polito/verigraph/tosca/XmlParsingUtils.java @@ -0,0 +1,142 @@ +/******************************************************************************* + * Copyright (c) 2017/18 Politecnico di Torino and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Apache License, Version 2.0 + * which accompanies this distribution, and is available at + * http://www.apache.org/licenses/LICENSE-2.0 + *******************************************************************************/ +package it.polito.verigraph.tosca; + +import java.io.FileInputStream; +import java.io.IOException; +import java.io.StringWriter; +import java.util.List; +import java.util.stream.Collectors; + +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBElement; +import javax.xml.bind.JAXBException; +import javax.xml.bind.Marshaller; +import javax.xml.bind.Unmarshaller; +import javax.xml.transform.Source; +import javax.xml.transform.stream.StreamSource; + +import com.sun.research.ws.wadl.ObjectFactory; + +import it.polito.verigraph.exception.DataNotFoundException; +import it.polito.tosca.jaxb.Configuration; +import it.polito.tosca.jaxb.Definitions; +import it.polito.tosca.jaxb.TDefinitions; +import it.polito.tosca.jaxb.TEntityTemplate; +import it.polito.tosca.jaxb.TExtensibleElements; +import it.polito.tosca.jaxb.TNodeTemplate; +import it.polito.tosca.jaxb.TRelationshipTemplate; +import it.polito.tosca.jaxb.TServiceTemplate; +import it.polito.tosca.jaxb.TTopologyTemplate; +import it.polito.verigraph.tosca.converter.grpc.ToscaGrpcUtils; + + +public class XmlParsingUtils { + + /** Returns a List of TServiceTemplate JAXB-generated objects, parsed from a TOSCA-compliant XML. */ + public static Definitions obtainDefinitions(String file) throws JAXBException, IOException, ClassCastException, DataNotFoundException { + // Create a JAXBContext capable of handling the generated classes + JAXBContext jc = JAXBContext.newInstance(ObjectFactory.class, TDefinitions.class, Configuration.class); + Unmarshaller u = jc.createUnmarshaller(); + + //Retrieve the TDefinitions object + Source source = new StreamSource(new FileInputStream(file)); + + JAXBElement<Definitions> rootElement = (JAXBElement<Definitions>)u.unmarshal(source, Definitions.class); + Definitions definitions = rootElement.getValue(); + return definitions; + } + + /** Returns a List of TServiceTemplate JAXB-generated objects, parsed from a TOSCA-compliant XML. */ + public static List<TServiceTemplate> obtainServiceTemplates(String file) throws JAXBException, IOException, ClassCastException, DataNotFoundException { + // Create a JAXBContext capable of handling the generated classes + JAXBContext jc = JAXBContext.newInstance(ObjectFactory.class, TDefinitions.class, Configuration.class); + Unmarshaller u = jc.createUnmarshaller(); + + //Retrieve the TDefinitions object + Source source = new StreamSource(new FileInputStream(file)); + + JAXBElement<TDefinitions> rootElement = (JAXBElement<TDefinitions>)u.unmarshal(source, TDefinitions.class); + TDefinitions definitions = rootElement.getValue(); + List<TExtensibleElements> elements = definitions.getServiceTemplateOrNodeTypeOrNodeTypeImplementation(); + + //Retrieve the list of ServiceTemplate in Definitions + List<TServiceTemplate> serviceTemplates = elements.stream() + .filter(p -> p instanceof TServiceTemplate) + .map(obj -> (TServiceTemplate) obj).collect(Collectors.toList()); + + if (serviceTemplates.isEmpty()) + throw new DataNotFoundException("There is no ServiceTemplate into the TOSCA XML file"); + return serviceTemplates; // Could be an empty list if there are no TServiceTemplate objects + } + + + /** Returns a List of TNodeTemplate JAXB-generated TOSCA objects. */ + public static List<TNodeTemplate> obtainNodeTemplates(TServiceTemplate serviceTemplate) throws DataNotFoundException { + TTopologyTemplate topologyTemplate = serviceTemplate.getTopologyTemplate(); + + // Retrieving a list of TNodeTemplate and TRelationshipTemplate JAXB objects + List<TEntityTemplate> entities = topologyTemplate.getNodeTemplateOrRelationshipTemplate(); + + // Retrieving a List containing only TNodeTemplates objects + List<TNodeTemplate> nodeTemplates = entities.stream() + .filter(p -> p instanceof TNodeTemplate) + .map(obj -> (TNodeTemplate) obj).collect(Collectors.toList()); + + if (nodeTemplates.isEmpty()) + throw new DataNotFoundException("There is no NodeTemplate into ServiceTemplate " + serviceTemplate.toString() + " and TopologyTemplate " + topologyTemplate.toString()); + return nodeTemplates; // Could be an empty list if there are no TNodeTemplate objects + } + + + /** Returns a List of TRelationshipTemplate JAXB-generated TOSCA objects. */ + public static List<TRelationshipTemplate> obtainRelationshipTemplates(TServiceTemplate serviceTemplate) throws DataNotFoundException { + TTopologyTemplate topologyTemplate = serviceTemplate.getTopologyTemplate(); + + // Retrieving a List of TNodeTemplate and TRelationshipTemplate JAXB objects + List<TEntityTemplate> entities = topologyTemplate.getNodeTemplateOrRelationshipTemplate(); + + // Retrieving a List containing only TRelationshipTemplate objects + List<TRelationshipTemplate> relationshipTemplates = entities.stream() + .filter(p -> p instanceof TRelationshipTemplate) + .map(obj -> (TRelationshipTemplate) obj).collect(Collectors.toList()); + + if (relationshipTemplates.isEmpty()) + throw new DataNotFoundException("There is no RelationshipTemplate into ServiceTemplate " + serviceTemplate.toString() + " and TopologyTemplate " + topologyTemplate.toString()); + return relationshipTemplates; // Could be an empty list if there are no TRelationshipTemplate objects + } + + + /** Returns the it.polito.tosca.jaxb.Configuration JAXB-generated TOSCA object of a TOSCA NodeTemplate. */ + public static Configuration obtainConfiguration(TNodeTemplate nodeTemplate) { + try { + Configuration configuration = (Configuration)nodeTemplate.getProperties().getAny(); + + //This could be eventually used to cross check node type and configuration type + //String typename = nodeTemplate.getType().getLocalPart().toLowerCase(); + return configuration; + + + } catch (NullPointerException | ClassCastException ex) { + //To be eventually defined a mechanism to distinguish hostnode from forwarder + System.out.println("[Warning] Node " + nodeTemplate.getId().toString() + + ": missing or invalid configuration, the node will be configured as a forwarder!" ); + Configuration defConf = new Configuration(); + defConf.setConfDescr(ToscaGrpcUtils.defaultDescr); + defConf.setConfID(ToscaGrpcUtils.defaultConfID); + + Configuration.FieldmodifierConfiguration defaultForward = new Configuration.FieldmodifierConfiguration(); + defaultForward.setName("DefaultForwarder"); + + defConf.setFieldmodifierConfiguration(defaultForward); + return defConf; + } + } + +} diff --git a/verigraph/src/it/polito/verigraph/tosca/YamlParsingUtils.java b/verigraph/src/it/polito/verigraph/tosca/YamlParsingUtils.java new file mode 100644 index 0000000..6e65ac9 --- /dev/null +++ b/verigraph/src/it/polito/verigraph/tosca/YamlParsingUtils.java @@ -0,0 +1,160 @@ +/*******************************************************************************
+ * Copyright (c) 2017/18 Politecnico di Torino and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Apache License, Version 2.0
+ * which accompanies this distribution, and is available at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+package it.polito.verigraph.tosca;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.StringWriter;
+import java.util.Map;
+
+import javax.xml.bind.JAXBException;
+
+import com.fasterxml.jackson.core.JsonParseException;
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.JsonMappingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.module.SimpleModule;
+import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
+
+import it.polito.verigraph.exception.BadRequestException;
+import it.polito.verigraph.exception.DataNotFoundException;
+import it.polito.verigraph.exception.InvalidServiceTemplateException;
+import it.polito.verigraph.tosca.serializer.YamlConfigSerializer;
+import it.polito.verigraph.tosca.yaml.beans.AntispamNode;
+import it.polito.verigraph.tosca.yaml.beans.CacheNode;
+import it.polito.verigraph.tosca.yaml.beans.ConfigurationYaml;
+import it.polito.verigraph.tosca.yaml.beans.DpiNode;
+import it.polito.verigraph.tosca.yaml.beans.EndhostNode;
+import it.polito.verigraph.tosca.yaml.beans.EndpointNode;
+import it.polito.verigraph.tosca.yaml.beans.FieldModifierNode;
+import it.polito.verigraph.tosca.yaml.beans.FirewallNode;
+import it.polito.verigraph.tosca.yaml.beans.MailClientNode;
+import it.polito.verigraph.tosca.yaml.beans.MailServerNode;
+import it.polito.verigraph.tosca.yaml.beans.NatNode;
+import it.polito.verigraph.tosca.yaml.beans.NodeTemplateYaml;
+import it.polito.verigraph.tosca.yaml.beans.RelationshipTemplateYaml;
+import it.polito.verigraph.tosca.yaml.beans.ServiceTemplateYaml;
+import it.polito.verigraph.tosca.yaml.beans.TopologyTemplateYaml;
+import it.polito.verigraph.tosca.yaml.beans.VpnAccessNode;
+import it.polito.verigraph.tosca.yaml.beans.VpnExitNode;
+import it.polito.verigraph.tosca.yaml.beans.WebClientNode;
+import it.polito.verigraph.tosca.yaml.beans.WebServerNode;
+
+public class YamlParsingUtils {
+
+ public static ServiceTemplateYaml obtainServiceTemplate(String filePath) throws InvalidServiceTemplateException {
+ ServiceTemplateYaml yamlServiceTemplate = new ServiceTemplateYaml();
+ ObjectMapper mapper = new ObjectMapper(new YAMLFactory());
+ mapper.enable(JsonParser.Feature.STRICT_DUPLICATE_DETECTION);
+
+ try {
+ yamlServiceTemplate = mapper.readValue(new File(filePath), ServiceTemplateYaml.class);
+ return yamlServiceTemplate;
+
+ } catch (JsonParseException e) {
+ throw new InvalidServiceTemplateException("The NodeTemplate IDs and the RelationshipTemplate IDs must be unique.");
+ } catch (JsonMappingException e) {
+ throw new InvalidServiceTemplateException("The provided file does not match the expected structure.");
+ } catch (InvalidServiceTemplateException e) {
+ throw new InvalidServiceTemplateException("The provided template contains errors or missing informations.");
+ } catch (IOException e) {
+ throw new InvalidServiceTemplateException("I/O error.");
+ }
+
+ }
+
+
+ public static Map<String, NodeTemplateYaml> obtainNodeTemplates(ServiceTemplateYaml yamlService) throws DataNotFoundException {
+ TopologyTemplateYaml yamlTopology;
+ try {
+ yamlTopology = yamlService.getTopology_template();
+ } catch(NullPointerException ex) {
+ throw new DataNotFoundException("The ServiceTemplate provided does not contain a TopologyTemplate.");
+ }
+ try {
+ Map<String, NodeTemplateYaml> nodes = yamlTopology.getNode_templates();
+ return nodes;
+ } catch(NullPointerException ex) {
+ throw new DataNotFoundException("The ServiceTemplate provided does not contain any NodeTemplates.");
+ }
+
+ }
+
+
+ public static Map<String, RelationshipTemplateYaml> obtainRelationshipTemplates(ServiceTemplateYaml yamlService) throws DataNotFoundException {
+ TopologyTemplateYaml yamlTopology;
+ try {
+ yamlTopology = yamlService.getTopology_template();
+ } catch(NullPointerException ex) {
+ throw new DataNotFoundException("The ServiceTemplate provided does not contain a TopologyTemplate.");
+ }
+ try {
+ Map<String,RelationshipTemplateYaml> relats = yamlTopology.getRelationship_templates();
+ return relats;
+ } catch(NullPointerException ex) {
+ throw new DataNotFoundException("The ServiceTemplate provided does not contain any RelationshipTemplates.");
+ }
+
+ }
+
+
+ public static String obtainConfiguration(NodeTemplateYaml node) throws BadRequestException {
+ ConfigurationYaml yamlConfiguration = null;
+ ObjectMapper mapper = new ObjectMapper();
+ SimpleModule module = new SimpleModule();
+ module.addSerializer(ConfigurationYaml.class, new YamlConfigSerializer());
+ mapper.registerModule(module);
+
+ // Find out node type, retrieve the corresponding configuration and convert it properly
+ try {
+ if(node instanceof AntispamNode) {
+ yamlConfiguration = ((AntispamNode)node).getProperties();
+ }else if(node instanceof CacheNode) {
+ yamlConfiguration = ((CacheNode)node).getProperties();
+ }else if(node instanceof DpiNode) {
+ yamlConfiguration = ((DpiNode)node).getProperties();
+ }else if(node instanceof EndhostNode) {
+ yamlConfiguration = ((EndhostNode)node).getProperties();
+ }else if(node instanceof EndpointNode) {
+ yamlConfiguration = ((EndpointNode)node).getProperties();
+ }else if(node instanceof FieldModifierNode) {
+ yamlConfiguration = ((FieldModifierNode)node).getProperties();
+ }else if(node instanceof FirewallNode) {
+ yamlConfiguration = ((FirewallNode)node).getProperties();
+ }else if(node instanceof MailClientNode) {
+ yamlConfiguration = ((MailClientNode)node).getProperties();
+ }else if(node instanceof MailServerNode) {
+ yamlConfiguration = ((MailServerNode)node).getProperties();
+ }else if(node instanceof NatNode) {
+ yamlConfiguration = ((NatNode)node).getProperties();
+ }else if(node instanceof VpnAccessNode) {
+ yamlConfiguration = ((VpnAccessNode)node).getProperties();
+ }else if(node instanceof VpnExitNode) {
+ yamlConfiguration = ((VpnExitNode)node).getProperties();
+ }else if(node instanceof WebClientNode) {
+ yamlConfiguration = ((WebClientNode)node).getProperties();
+ }else if(node instanceof WebServerNode) {
+ yamlConfiguration = ((WebServerNode)node).getProperties();
+ }else {
+ throw new BadRequestException("The provided node is of unknown type, unable to retrieve the node configuration");
+ }
+
+ String stringConfiguration = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(yamlConfiguration);
+ if (!stringConfiguration.equals("null"))
+ return stringConfiguration;
+ else
+ return "[]";
+
+ } catch (JsonProcessingException | NullPointerException e) {
+ throw new BadRequestException("Not able to retrieve a valid configuration");
+ }
+ }
+
+}
\ No newline at end of file diff --git a/verigraph/src/it/polito/verigraph/tosca/converter/grpc/GraphToGrpc.java b/verigraph/src/it/polito/verigraph/tosca/converter/grpc/GraphToGrpc.java new file mode 100644 index 0000000..fb52c7b --- /dev/null +++ b/verigraph/src/it/polito/verigraph/tosca/converter/grpc/GraphToGrpc.java @@ -0,0 +1,101 @@ +/*******************************************************************************
+ * Copyright (c) 2018 Politecnico di Torino and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Apache License, Version 2.0
+ * which accompanies this distribution, and is available at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+package it.polito.verigraph.tosca.converter.grpc;
+
+import java.util.Map;
+
+import it.polito.verigraph.grpc.NodeTemplateGrpc;
+import it.polito.verigraph.grpc.RelationshipTemplateGrpc;
+import it.polito.verigraph.grpc.TopologyTemplateGrpc;
+import it.polito.verigraph.grpc.ToscaConfigurationGrpc;
+import it.polito.verigraph.grpc.ToscaTestGrpc;
+import it.polito.verigraph.grpc.ToscaVerificationGrpc;
+import it.polito.verigraph.model.Configuration;
+import it.polito.verigraph.model.Graph;
+import it.polito.verigraph.model.Neighbour;
+import it.polito.verigraph.model.Node;
+import it.polito.verigraph.model.Test;
+import it.polito.verigraph.model.Verification;
+
+public class GraphToGrpc {
+
+ /** Mapping method --> from model Graph to grpc TopologyTemplate */
+ public static TopologyTemplateGrpc obtainTopologyTemplate(Graph graph) {
+ TopologyTemplateGrpc.Builder topol = TopologyTemplateGrpc.newBuilder();
+ topol.setId(String.valueOf(graph.getId()));
+
+ //NodeTemplate
+ for(Node node : graph.getNodes().values()) {
+ NodeTemplateGrpc nt = obtainNodeTemplate(node);
+ topol.addNodeTemplate(nt);
+ //RelationshipTemplate
+ Map<Long,Neighbour> neighMap = node.getNeighbours();
+ for (Map.Entry<Long, Neighbour> myentry : neighMap.entrySet()) {
+ Neighbour neigh = myentry.getValue();
+ RelationshipTemplateGrpc relat = obtainRelationshipTemplate(neigh, node);
+ topol.addRelationshipTemplate(relat);
+ }
+ }
+ return topol.build();
+ }
+
+
+ /** Mapping method --> from model Node to grpc NodeTemplate */
+ private static NodeTemplateGrpc obtainNodeTemplate(Node node){
+ NodeTemplateGrpc.Builder nodegrpc = NodeTemplateGrpc.newBuilder();
+
+ nodegrpc.setId(String.valueOf(node.getId()));
+ nodegrpc.setName(node.getName());
+ nodegrpc.setType(NodeTemplateGrpc.Type.valueOf(node.getFunctional_type().toLowerCase()));
+
+ ToscaConfigurationGrpc config = obtainToscaConfiguration(node.getConfiguration());
+ nodegrpc.setConfiguration(config);
+
+ return nodegrpc.build();
+ }
+
+
+ /** Mapping method --> from model Neighbour to grpc RelationshipTemplate */
+ private static RelationshipTemplateGrpc obtainRelationshipTemplate(Neighbour neigh, Node sourceNode) {
+ RelationshipTemplateGrpc.Builder relat = RelationshipTemplateGrpc.newBuilder();
+ relat.setId(String.valueOf(sourceNode.getId()));
+ //Neighbour does not have a neighbourID! RelationshipTemplate does, so it is set to sourceNodeID
+ relat.setIdSourceNodeTemplate(String.valueOf(sourceNode.getId()));
+ relat.setIdTargetNodeTemplate(String.valueOf(neigh.getId()));
+ relat.setName(sourceNode.getName()+"to"+neigh.getName());
+ return relat.build();
+ }
+
+
+ /** Mapping method --> from model Configuration to grpc ToscaConfigurationGrpc */
+ private static ToscaConfigurationGrpc obtainToscaConfiguration(Configuration conf) {
+ return ToscaConfigurationGrpc.newBuilder()
+ .setId(conf.getId())
+ .setDescription(conf.getDescription())
+ .setConfiguration(conf.getConfiguration().toString())
+ .build();
+ }
+
+ /** Mapping method --> from model Verification to grpc ToscaVerificationGrpc */
+ public static ToscaVerificationGrpc obtainToscaVerification(Verification verify){
+ ToscaVerificationGrpc.Builder ver = ToscaVerificationGrpc.newBuilder();
+ ver.setComment(verify.getComment());
+ ver.setResult(verify.getResult());
+ for(Test test:verify.getTests()){
+ ToscaTestGrpc.Builder tst = ToscaTestGrpc.newBuilder().setResult(test.getResult());
+ for(Node node:test.getPath()){
+ NodeTemplateGrpc nodetempl = obtainNodeTemplate(node);
+ tst.addNodeTemplate(nodetempl);
+ }
+ ver.addTest(tst);
+ }
+ return ver.build();
+ }
+
+}
diff --git a/verigraph/src/it/polito/verigraph/tosca/converter/grpc/GrpcToGraph.java b/verigraph/src/it/polito/verigraph/tosca/converter/grpc/GrpcToGraph.java new file mode 100644 index 0000000..76906b3 --- /dev/null +++ b/verigraph/src/it/polito/verigraph/tosca/converter/grpc/GrpcToGraph.java @@ -0,0 +1,150 @@ +/*******************************************************************************
+ * Copyright (c) 2018 Politecnico di Torino and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Apache License, Version 2.0
+ * which accompanies this distribution, and is available at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+package it.polito.verigraph.tosca.converter.grpc;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+import it.polito.verigraph.exception.BadRequestException;
+import it.polito.verigraph.grpc.NodeTemplateGrpc;
+import it.polito.verigraph.grpc.RelationshipTemplateGrpc;
+import it.polito.verigraph.grpc.TopologyTemplateGrpc;
+import it.polito.verigraph.grpc.ToscaConfigurationGrpc;
+import it.polito.verigraph.model.Configuration;
+import it.polito.verigraph.model.Graph;
+import it.polito.verigraph.model.Neighbour;
+import it.polito.verigraph.model.Node;
+
+public class GrpcToGraph {
+
+ /** Mapping method --> from grpc TopologyTemplateGrpc to model Graph */
+ public static Graph deriveGraph(TopologyTemplateGrpc request) throws BadRequestException, JsonProcessingException, IOException {
+ Graph graph = new Graph();
+ Map<Long, Node> nodes = new HashMap<>();
+
+ try {
+ //Create a list of Node without Neighbour
+ for(NodeTemplateGrpc nodetempl : request.getNodeTemplateList()){
+ Node node = deriveNode(nodetempl);
+ //It necessary to check uniqueness here otherwise a .put with the same key will overwrite the old node
+ if(nodes.containsKey(node.getId()))
+ throw new BadRequestException("The NodeTemplate ID must be unique.");
+ else
+ nodes.put(node.getId(), node);
+ }
+
+ //Add Neighbour to the Node of the list
+ List<RelationshipTemplateGrpc> relatList = request.getRelationshipTemplateList();
+ nodes = deriveNeighboursNode(nodes, relatList);
+
+ //Add Node and ID to the graph
+ graph.setNodes(nodes);
+ try {
+ graph.setId(Long.valueOf(request.getId()));
+ } catch(NumberFormatException ex) {
+ throw new BadRequestException("If you want to store your TopologyTemplate on this server,"
+ + "the TopologyTemplate ID must be a number.");
+ }
+
+ return graph;
+
+ } catch (NullPointerException e) {
+ throw new BadRequestException("The TopologyTemplate received has invalid fields.");
+ }
+
+ }
+
+
+ /** Mapping method --> from grpc NodeTemplate to model Node (with no Neighbour) */
+ private static Node deriveNode(NodeTemplateGrpc nodegrpc) throws BadRequestException, JsonProcessingException, IOException {
+ Node node = new Node();
+ try {
+ try {
+ node.setId(Long.valueOf(nodegrpc.getId()));
+ } catch(NumberFormatException ex) {
+ throw new BadRequestException("The NodeTemplate ID must be a number.");
+ }
+
+ node.setName(nodegrpc.getName());
+ Configuration conf = deriveConfiguration(nodegrpc.getConfiguration());
+ node.setConfiguration(conf);
+ node.setFunctional_type(nodegrpc.getType().toString());
+
+ } catch(NullPointerException ex) {
+ throw new BadRequestException("A NodeTemplate has wrong fields representation.");
+ }
+
+ return node;
+ }
+
+
+
+ /** Mapping method --> from a list of model Node to a list of model Node with their Neighbour */
+ private static Map<Long,Node> deriveNeighboursNode(Map<Long,Node> nodes, List<RelationshipTemplateGrpc> relatList)
+ throws BadRequestException{
+ Map<Long,Node> updNodes = nodes; //new list to be filled with updated Node (update = Node + its Neighbour)
+ for(RelationshipTemplateGrpc relat : relatList) {
+ try {
+ //Retrieve the target Node name and generate a new Neighbour
+ String neighName = updNodes.get(Long.valueOf(relat.getIdTargetNodeTemplate())).getName();
+ Neighbour neigh = new Neighbour();
+ neigh.setName(neighName);
+ neigh.setId(Long.valueOf(relat.getId()));
+
+ //Retrieve the Neighbour map of the source Node and add the Neighbour
+ Node source = updNodes.get(Long.valueOf(relat.getIdSourceNodeTemplate()));
+ Map<Long,Neighbour> sourceNodeNeighMap = source.getNeighbours();
+ if(sourceNodeNeighMap.containsKey(neigh.getId()))
+ throw new BadRequestException("The RelationshipTemplate ID must be unique.");
+ else
+ sourceNodeNeighMap.put(neigh.getId(), neigh);
+ source.setNeighbours(sourceNodeNeighMap);
+
+ //Update the Node list
+ updNodes.put(Long.valueOf(relat.getIdSourceNodeTemplate()), source);
+ } catch(NullPointerException | NumberFormatException ex) {
+ throw new BadRequestException("A RelationshipTemplate has wrong fields representation.");
+ }
+ }
+ return updNodes;
+ }
+
+ /** Mapping method --> from ToscaConfiguration to model Configuration */
+ private static Configuration deriveConfiguration(ToscaConfigurationGrpc request)
+ throws BadRequestException, JsonProcessingException, IOException {
+ Configuration conf = new Configuration();
+ ObjectMapper mapper = new ObjectMapper();
+ JsonNode rootNode = null;
+
+ try {
+ conf.setId(request.getId());
+ } catch (NullPointerException e) {}
+
+ try {
+ conf.setDescription(request.getDescription());
+ } catch (NullPointerException e) {}
+
+ try {
+ if ("".equals(request.getConfiguration()))
+ rootNode=mapper.readTree("[]");
+ else
+ rootNode = mapper.readTree(request.getConfiguration());
+ } catch (NullPointerException e) {
+ rootNode=mapper.readTree("[]");
+ }
+ conf.setConfiguration(rootNode);
+ return conf;
+ }
+}
diff --git a/verigraph/src/it/polito/verigraph/tosca/converter/grpc/GrpcToXml.java b/verigraph/src/it/polito/verigraph/tosca/converter/grpc/GrpcToXml.java new file mode 100644 index 0000000..002737a --- /dev/null +++ b/verigraph/src/it/polito/verigraph/tosca/converter/grpc/GrpcToXml.java @@ -0,0 +1,145 @@ +/*******************************************************************************
+ * Copyright (c) 2018 Politecnico di Torino and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Apache License, Version 2.0
+ * which accompanies this distribution, and is available at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+package it.polito.verigraph.tosca.converter.grpc;
+
+import java.io.IOException;
+import java.util.List;
+
+import javax.xml.namespace.QName;
+
+import it.polito.tosca.jaxb.Configuration;
+import it.polito.tosca.jaxb.Definitions;
+import it.polito.tosca.jaxb.TEntityTemplate.Properties;
+import it.polito.tosca.jaxb.TNodeTemplate;
+import it.polito.tosca.jaxb.TRelationshipTemplate;
+import it.polito.tosca.jaxb.TRelationshipTemplate.SourceElement;
+import it.polito.tosca.jaxb.TRelationshipTemplate.TargetElement;
+import it.polito.tosca.jaxb.TServiceTemplate;
+import it.polito.tosca.jaxb.TTopologyTemplate;
+import it.polito.verigraph.exception.BadRequestException;
+import it.polito.verigraph.grpc.NodeTemplateGrpc;
+import it.polito.verigraph.grpc.RelationshipTemplateGrpc;
+import it.polito.verigraph.grpc.TopologyTemplateGrpc;
+import it.polito.verigraph.grpc.ToscaConfigurationGrpc;
+import it.polito.verigraph.tosca.MappingUtils;
+
+public class GrpcToXml {
+
+ public static Definitions mapGraph(TopologyTemplateGrpc topologyGrpc) {
+ Definitions definitions = new Definitions();
+ TServiceTemplate serviceTemplate = new TServiceTemplate();
+ TTopologyTemplate topologyTemplate = new TTopologyTemplate();
+
+ for(NodeTemplateGrpc node : topologyGrpc.getNodeTemplateList()) {
+ TNodeTemplate nodeTemplate = mapNode(node);
+ topologyTemplate.getNodeTemplateOrRelationshipTemplate().add(nodeTemplate);
+ }
+ for(RelationshipTemplateGrpc relat : topologyGrpc.getRelationshipTemplateList()) {
+ TRelationshipTemplate relationshipTemplate = mapRelationship(relat, topologyGrpc.getNodeTemplateList());
+ topologyTemplate.getNodeTemplateOrRelationshipTemplate().add(relationshipTemplate);
+ }
+
+ try {
+ serviceTemplate.setId(String.valueOf(topologyGrpc.getId()));
+ } catch (NullPointerException e) {
+ throw new NullPointerException("The TopologyTemplateGrpc must have an ID.");
+ }
+ serviceTemplate.setTopologyTemplate(topologyTemplate);
+ definitions.getServiceTemplateOrNodeTypeOrNodeTypeImplementation().add(serviceTemplate);
+ return definitions;
+ }
+
+
+ private static TNodeTemplate mapNode(NodeTemplateGrpc node){
+ TNodeTemplate nodeTemplate = new TNodeTemplate();
+
+ try {
+ nodeTemplate.setId(String.valueOf(node.getId()));
+ } catch (NullPointerException e) {
+ throw new NullPointerException("The NodeTemplateGrpc must have an ID.");
+ }
+ try {
+ nodeTemplate.setName(node.getName());
+ } catch (NullPointerException e) {
+ throw new NullPointerException("The NodeTemplateGrpc must have a name.");
+ }
+
+ try {
+ //QName type = new QName("http://docs.oasis-open.org/tosca/ns/2011/12/ToscaVerigraphDefinition")
+ QName type = new QName("http://docs.oasis-open.org/tosca/ns/2011/12",
+ node.getType().toString().substring(0, 1).toUpperCase() +
+ node.getType().toString().substring(1) + "Type");
+ nodeTemplate.setType(type);
+ } catch (NullPointerException e) {
+ throw new NullPointerException("The NodeTemplateGrpc must have a valid type.");
+ }
+
+ Configuration config = mapModelConfiguration(node.getConfiguration(), node.getType().toString().toLowerCase());
+ nodeTemplate.setProperties(new Properties());
+ nodeTemplate.getProperties().setAny(config);
+ return nodeTemplate;
+ }
+
+
+ private static TRelationshipTemplate mapRelationship(RelationshipTemplateGrpc relat, List<NodeTemplateGrpc> nodeList) {
+ TRelationshipTemplate relationship = new TRelationshipTemplate();
+ SourceElement source = new SourceElement();
+ TargetElement target = new TargetElement();
+ int check = 0;
+
+ TNodeTemplate sourceNode = new TNodeTemplate();
+ TNodeTemplate targetNode = new TNodeTemplate();
+
+ try {
+ for(NodeTemplateGrpc node : nodeList) {
+ if(node.getId().equals(relat.getIdSourceNodeTemplate())) {
+ sourceNode = mapNode(node);
+ check++;
+ }
+ if(node.getId().equals(relat.getIdTargetNodeTemplate())) {
+ targetNode = mapNode(node);
+ check++;
+ }
+ }
+ } catch (NullPointerException e) {
+ throw new BadRequestException("A RelationshipTemplateGrpc must contain both source and target node ID.");
+ }
+ if(check != 2)
+ throw new BadRequestException("A RelationshipTemplateGrpc must contain both source and target node ID.");
+
+ source.setRef(sourceNode);
+ target.setRef(targetNode);
+
+ relationship.setId(relat.getId()); //TODO da valutare
+ relationship.setSourceElement(source);
+ relationship.setTargetElement(target);
+ relationship.setName(sourceNode.getName()+"To"+targetNode.getName());
+
+ return relationship;
+ }
+
+
+ private static it.polito.tosca.jaxb.Configuration mapModelConfiguration(ToscaConfigurationGrpc toscaConfigurationGrpc, String type) {
+ it.polito.tosca.jaxb.Configuration configuration = new it.polito.tosca.jaxb.Configuration();
+ try {
+ //We are passing the configuration type to the Deserializer context
+ configuration = MappingUtils.obtainToscaConfiguration(toscaConfigurationGrpc, type);
+
+ //In Graph, ID and DESCRIPTION are always empty
+ //configuration.setConfID(confGrpc.getId());
+ //configuration.setConfDescr(confGrpc.getDescription());
+
+ } catch (IOException | NullPointerException e) {
+ e.printStackTrace();
+ }
+ return configuration;
+ }
+
+}
+
diff --git a/verigraph/src/it/polito/verigraph/tosca/converter/grpc/GrpcToYaml.java b/verigraph/src/it/polito/verigraph/tosca/converter/grpc/GrpcToYaml.java new file mode 100644 index 0000000..64f8ae4 --- /dev/null +++ b/verigraph/src/it/polito/verigraph/tosca/converter/grpc/GrpcToYaml.java @@ -0,0 +1,284 @@ +/*******************************************************************************
+ * Copyright (c) 2018 Politecnico di Torino and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Apache License, Version 2.0
+ * which accompanies this distribution, and is available at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+package it.polito.verigraph.tosca.converter.grpc;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.List;
+
+import com.fasterxml.jackson.core.JsonParseException;
+import com.fasterxml.jackson.databind.InjectableValues;
+import com.fasterxml.jackson.databind.JsonMappingException;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.module.SimpleModule;
+import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
+
+import it.polito.neo4j.jaxb.FunctionalTypes;
+import it.polito.verigraph.exception.BadRequestException;
+import it.polito.verigraph.grpc.NodeTemplateGrpc;
+import it.polito.verigraph.grpc.RelationshipTemplateGrpc;
+import it.polito.verigraph.grpc.TopologyTemplateGrpc;
+import it.polito.verigraph.tosca.deserializer.YamlConfigurationDeserializer;
+import it.polito.verigraph.tosca.yaml.beans.AntispamConfigurationYaml;
+import it.polito.verigraph.tosca.yaml.beans.AntispamNode;
+import it.polito.verigraph.tosca.yaml.beans.CacheConfigurationYaml;
+import it.polito.verigraph.tosca.yaml.beans.CacheNode;
+import it.polito.verigraph.tosca.yaml.beans.ConfigurationYaml;
+import it.polito.verigraph.tosca.yaml.beans.DpiConfigurationYaml;
+import it.polito.verigraph.tosca.yaml.beans.DpiNode;
+import it.polito.verigraph.tosca.yaml.beans.EndhostConfigurationYaml;
+import it.polito.verigraph.tosca.yaml.beans.EndhostNode;
+import it.polito.verigraph.tosca.yaml.beans.EndpointConfigurationYaml;
+import it.polito.verigraph.tosca.yaml.beans.EndpointNode;
+import it.polito.verigraph.tosca.yaml.beans.FieldModifierConfigurationYaml;
+import it.polito.verigraph.tosca.yaml.beans.FieldModifierNode;
+import it.polito.verigraph.tosca.yaml.beans.FirewallConfigurationYaml;
+import it.polito.verigraph.tosca.yaml.beans.FirewallNode;
+import it.polito.verigraph.tosca.yaml.beans.MailClientConfigurationYaml;
+import it.polito.verigraph.tosca.yaml.beans.MailClientNode;
+import it.polito.verigraph.tosca.yaml.beans.MailServerConfigurationYaml;
+import it.polito.verigraph.tosca.yaml.beans.MailServerNode;
+import it.polito.verigraph.tosca.yaml.beans.NatConfigurationYaml;
+import it.polito.verigraph.tosca.yaml.beans.NatNode;
+import it.polito.verigraph.tosca.yaml.beans.NodeTemplateYaml;
+import it.polito.verigraph.tosca.yaml.beans.RelationshipTemplateYaml;
+import it.polito.verigraph.tosca.yaml.beans.ServiceTemplateYaml;
+import it.polito.verigraph.tosca.yaml.beans.TopologyTemplateYaml;
+import it.polito.verigraph.tosca.yaml.beans.VpnAccessConfigurationYaml;
+import it.polito.verigraph.tosca.yaml.beans.VpnAccessNode;
+import it.polito.verigraph.tosca.yaml.beans.VpnExitConfigurationYaml;
+import it.polito.verigraph.tosca.yaml.beans.VpnExitNode;
+import it.polito.verigraph.tosca.yaml.beans.WebClientConfigurationYaml;
+import it.polito.verigraph.tosca.yaml.beans.WebClientNode;
+import it.polito.verigraph.tosca.yaml.beans.WebServerConfigurationYaml;
+import it.polito.verigraph.tosca.yaml.beans.WebServerNode;
+
+public class GrpcToYaml {
+ public static ServiceTemplateYaml mapGraphYaml(TopologyTemplateGrpc topologyGrpc) {
+ ServiceTemplateYaml serviceYaml = new ServiceTemplateYaml();
+ TopologyTemplateYaml topologyYaml = new TopologyTemplateYaml();
+
+ topologyYaml.setNode_templates(new HashMap<String,NodeTemplateYaml>());
+ topologyYaml.setRelationship_templates(new HashMap<String,RelationshipTemplateYaml>());
+ serviceYaml.setMetadata(new HashMap<String,String>());
+
+ for(NodeTemplateGrpc node : topologyGrpc.getNodeTemplateList()) {
+ NodeTemplateYaml nodeTemplate = new NodeTemplateYaml();
+ try {
+ nodeTemplate = mapNodeYaml(node);
+ } catch (IOException e) {
+ throw new BadRequestException("Error while mapping a Node in Yaml object.");
+ }
+ topologyYaml.getNode_templates().put(String.valueOf(node.getId()), nodeTemplate);
+ //shall we catch NumberFormatException?
+ }
+ for(RelationshipTemplateGrpc relationship : topologyGrpc.getRelationshipTemplateList()) {
+ RelationshipTemplateYaml rel = mapRelationshipYaml(relationship, topologyGrpc.getNodeTemplateList());
+ topologyYaml.getRelationship_templates().put(String.valueOf(relationship.getId()), rel);
+ }
+
+ serviceYaml.getMetadata().put("template_id", String.valueOf(topologyGrpc.getId()));
+ serviceYaml.setTopology_template(topologyYaml);
+ return serviceYaml;
+ }
+
+
+ private static NodeTemplateYaml mapNodeYaml(NodeTemplateGrpc node) throws JsonParseException, JsonMappingException, IOException {
+
+ ObjectMapper mapper = new ObjectMapper(new YAMLFactory());
+ SimpleModule module = new SimpleModule();
+ String stringConfig = null;
+ try {
+ stringConfig = node.getConfiguration().getConfiguration();
+ } catch (NullPointerException e) {
+ throw new NullPointerException("A NodeTemplateGrpc does not contain the configuration.");
+ }
+ JsonNode nodeConfig = mapper.readTree(stringConfig);
+ //Passing the configuration type to the Deserializer context
+ module.addDeserializer(ConfigurationYaml.class, new YamlConfigurationDeserializer());
+ mapper.registerModule(module);
+
+ if(node.getType() == null)
+ throw new NullPointerException("A NodeTemplateGrpc does not contain a type.");
+ ConfigurationYaml yamlConfig = mapper
+ .reader(new InjectableValues.Std().addValue("type", node.getType().toString().toLowerCase()))
+ .forType(ConfigurationYaml.class)
+ .readValue(nodeConfig);
+
+
+ FunctionalTypes nodeType = FunctionalTypes.valueOf(node.getType().toString().toUpperCase());
+ switch(nodeType) {
+ case ANTISPAM:
+ AntispamNode antispamNode = new AntispamNode();
+ antispamNode.setName(node.getName());
+ antispamNode.setType("verigraph.nodeTypes." +
+ node.getType().toString().substring(0, 1).toUpperCase() +
+ node.getType().toString().substring(1));
+ antispamNode.setProperties((AntispamConfigurationYaml) yamlConfig);
+ return antispamNode;
+
+ case CACHE:
+ CacheNode cacheNode = new CacheNode();
+ cacheNode.setName(node.getName());
+ cacheNode.setType("verigraph.nodeTypes." +
+ node.getType().toString().substring(0, 1).toUpperCase() +
+ node.getType().toString().substring(1));
+ cacheNode.setProperties((CacheConfigurationYaml) yamlConfig);
+ return cacheNode;
+
+ case DPI:
+ DpiNode dpiNode = new DpiNode();
+ dpiNode.setName(node.getName());
+ dpiNode.setType("verigraph.nodeTypes." +
+ node.getType().toString().substring(0, 1).toUpperCase() +
+ node.getType().toString().substring(1));
+ dpiNode.setProperties((DpiConfigurationYaml) yamlConfig);
+ return dpiNode;
+
+ case ENDHOST:
+ EndhostNode endhostNode = new EndhostNode();
+ endhostNode.setName(node.getName());
+ endhostNode.setType("verigraph.nodeTypes." +
+ node.getType().toString().substring(0, 1).toUpperCase() +
+ node.getType().toString().substring(1));
+ endhostNode.setProperties((EndhostConfigurationYaml) yamlConfig);
+ return endhostNode;
+
+ case ENDPOINT:
+ EndpointNode endpointNode = new EndpointNode();
+ endpointNode.setName(node.getName());
+ endpointNode.setType("verigraph.nodeTypes." +
+ node.getType().toString().substring(0, 1).toUpperCase() +
+ node.getType().toString().substring(1));
+ endpointNode.setProperties((EndpointConfigurationYaml) yamlConfig);
+ return endpointNode;
+
+ case FIELDMODIFIER:
+ FieldModifierNode fieldmodifierNode = new FieldModifierNode();
+ fieldmodifierNode.setName(node.getName());
+ fieldmodifierNode.setType("verigraph.nodeTypes." +
+ node.getType().toString().substring(0, 1).toUpperCase() +
+ node.getType().toString().substring(1));
+ fieldmodifierNode.setProperties((FieldModifierConfigurationYaml) yamlConfig);
+ return fieldmodifierNode;
+
+ case FIREWALL:
+ FirewallNode firewallNode = new FirewallNode();
+ firewallNode.setName(node.getName());
+ firewallNode.setType("verigraph.nodeTypes." +
+ node.getType().toString().substring(0, 1).toUpperCase() +
+ node.getType().toString().substring(1));
+ firewallNode.setProperties((FirewallConfigurationYaml) yamlConfig);
+ return firewallNode;
+
+ case MAILCLIENT:
+ MailClientNode mailclientNode = new MailClientNode();
+ mailclientNode.setName(node.getName());
+ mailclientNode.setType("verigraph.nodeTypes." +
+ node.getType().toString().substring(0, 1).toUpperCase() +
+ node.getType().toString().substring(1));
+ mailclientNode.setProperties((MailClientConfigurationYaml) yamlConfig);
+ return mailclientNode;
+
+ case MAILSERVER:
+ MailServerNode mailserverNode = new MailServerNode();
+ mailserverNode.setName(node.getName());
+ mailserverNode.setType("verigraph.nodeTypes." +
+ node.getType().toString().substring(0, 1).toUpperCase() +
+ node.getType().toString().substring(1));
+ mailserverNode.setProperties((MailServerConfigurationYaml) yamlConfig);
+ return mailserverNode;
+
+ case NAT:
+ NatNode natNode = new NatNode();
+ natNode.setName(node.getName());
+ natNode.setType("verigraph.nodeTypes." +
+ node.getType().toString().substring(0, 1).toUpperCase() +
+ node.getType().toString().substring(1));
+ natNode.setProperties((NatConfigurationYaml) yamlConfig);
+ return natNode;
+
+ case VPNACCESS:
+ VpnAccessNode vpnaccessNode = new VpnAccessNode();
+ vpnaccessNode.setName(node.getName());
+ vpnaccessNode.setType("verigraph.nodeTypes." +
+ node.getType().toString().substring(0, 1).toUpperCase() +
+ node.getType().toString().substring(1));
+ vpnaccessNode.setProperties((VpnAccessConfigurationYaml) yamlConfig);
+ return vpnaccessNode;
+
+ case VPNEXIT:
+ VpnExitNode vpnexitNode = new VpnExitNode();
+ vpnexitNode.setName(node.getName());
+ vpnexitNode.setType("verigraph.nodeTypes." +
+ node.getType().toString().substring(0, 1).toUpperCase() +
+ node.getType().toString().substring(1));
+ vpnexitNode.setProperties((VpnExitConfigurationYaml) yamlConfig);
+ return vpnexitNode;
+
+ case WEBCLIENT:
+ WebClientNode webclientNode = new WebClientNode();
+ webclientNode.setName(node.getName());
+ webclientNode.setType("verigraph.nodeTypes." +
+ node.getType().toString().substring(0, 1).toUpperCase() +
+ node.getType().toString().substring(1));
+ webclientNode.setProperties((WebClientConfigurationYaml) yamlConfig);
+ return webclientNode;
+
+ case WEBSERVER:
+ WebServerNode webserverNode = new WebServerNode();
+ webserverNode.setName(node.getName());
+ webserverNode.setType("verigraph.nodeTypes." +
+ node.getType().toString().substring(0, 1).toUpperCase() +
+ node.getType().toString().substring(1));
+ webserverNode.setProperties((WebServerConfigurationYaml) yamlConfig);
+ return webserverNode;
+
+ default:
+ FieldModifierNode defaultNode = new FieldModifierNode();
+ defaultNode.setName(node.getName());
+ defaultNode.setType("verigraph.nodeTypes.Fieldmodifier");
+ defaultNode.setProperties(new FieldModifierConfigurationYaml());
+ return defaultNode;
+ }
+
+ }
+
+ private static RelationshipTemplateYaml mapRelationshipYaml(RelationshipTemplateGrpc relat, List<NodeTemplateGrpc> nodeList) {
+ RelationshipTemplateYaml relationship = new RelationshipTemplateYaml();
+ relationship.setProperties(new HashMap<String,String>());
+ String sourceNode = null;
+ String targetNode = null;
+ int check = 0;
+
+ relationship.setType("verigraph.relationshipType.generic");
+ relationship.getProperties().put("source_id", String.valueOf(relat.getIdSourceNodeTemplate())); //to be catched?
+ relationship.getProperties().put("target_id", String.valueOf(relat.getIdTargetNodeTemplate()));
+
+ for(NodeTemplateGrpc node : nodeList) {
+ if(node.getId().equals(relat.getIdSourceNodeTemplate())) {
+ sourceNode = node.getName();
+ check++;
+ }
+ if(node.getId().equals(relat.getIdTargetNodeTemplate())) {
+ targetNode = node.getName();
+ check++;
+ }
+ }
+
+ if(check!=2)
+ throw new BadRequestException("A RelationshipTemplateGrpc must contain both source and target node ID.");
+
+ relationship.getProperties().put("name", sourceNode+"To"+targetNode);
+
+ return relationship;
+ }
+}
+
diff --git a/verigraph/src/it/polito/verigraph/tosca/converter/grpc/ToscaGrpcUtils.java b/verigraph/src/it/polito/verigraph/tosca/converter/grpc/ToscaGrpcUtils.java new file mode 100644 index 0000000..e43ef21 --- /dev/null +++ b/verigraph/src/it/polito/verigraph/tosca/converter/grpc/ToscaGrpcUtils.java @@ -0,0 +1,18 @@ +/*******************************************************************************
+ * Copyright (c) 2018 Politecnico di Torino and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Apache License, Version 2.0
+ * which accompanies this distribution, and is available at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+package it.polito.verigraph.tosca.converter.grpc;
+
+public class ToscaGrpcUtils {
+
+ /** Default configuration for a Tosca NodeTemplate non compliant with Verigraph types*/
+ public static final String defaultConfID = new String("");
+ public static final String defaultDescr = new String("Default Configuration");
+ public static final String defaultConfig = new String("[]");
+
+}
diff --git a/verigraph/src/it/polito/verigraph/tosca/converter/grpc/XmlToGrpc.java b/verigraph/src/it/polito/verigraph/tosca/converter/grpc/XmlToGrpc.java new file mode 100644 index 0000000..426bb4a --- /dev/null +++ b/verigraph/src/it/polito/verigraph/tosca/converter/grpc/XmlToGrpc.java @@ -0,0 +1,160 @@ +/*******************************************************************************
+ * Copyright (c) 2018 Politecnico di Torino and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Apache License, Version 2.0
+ * which accompanies this distribution, and is available at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+package it.polito.verigraph.tosca.converter.grpc;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.xml.bind.JAXBException;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+
+import it.polito.tosca.jaxb.TNodeTemplate;
+import it.polito.tosca.jaxb.TRelationshipTemplate;
+import it.polito.tosca.jaxb.TServiceTemplate;
+import it.polito.verigraph.exception.BadRequestException;
+import it.polito.verigraph.exception.DataNotFoundException;
+import it.polito.verigraph.grpc.NodeTemplateGrpc;
+import it.polito.verigraph.grpc.NodeTemplateGrpc.Type;
+import it.polito.verigraph.grpc.RelationshipTemplateGrpc;
+import it.polito.verigraph.grpc.TopologyTemplateGrpc;
+import it.polito.verigraph.grpc.ToscaConfigurationGrpc;
+import it.polito.verigraph.tosca.MappingUtils;
+import it.polito.verigraph.tosca.XmlParsingUtils;
+
+public class XmlToGrpc {
+
+ /** Returns the (first) TopologyTemplate found in the TOSCA-compliant XML file */
+ public static TopologyTemplateGrpc obtainTopologyTemplateGrpc (String filepath)
+ throws IOException, JAXBException, DataNotFoundException, ClassCastException, BadRequestException{
+ List<TServiceTemplate> serviceTList = XmlParsingUtils.obtainServiceTemplates(filepath);
+ TServiceTemplate serviceTemplate = serviceTList.get(0); //obtain only the first ServiceTemplate of the TOSCA compliance file
+
+ //Retrieving of list of NodeTemplate and RelationshipTemplate
+ List<NodeTemplateGrpc> nodes = new ArrayList<NodeTemplateGrpc>();
+ List<RelationshipTemplateGrpc> relats = new ArrayList<RelationshipTemplateGrpc>();
+ List<TNodeTemplate> tNodes = XmlParsingUtils.obtainNodeTemplates(serviceTemplate);
+ for(TNodeTemplate nt : tNodes) {
+ for(NodeTemplateGrpc alreadyAddedNode : nodes)
+ if(alreadyAddedNode.getId().equals(nt.getId()))
+ throw new BadRequestException("The NodeTemplate ID must be unique.");
+ nodes.add(parseNodeTemplate(nt));
+ }
+ for(TRelationshipTemplate rt : XmlParsingUtils.obtainRelationshipTemplates(serviceTemplate)) {
+ if(!tNodes.contains(rt.getSourceElement().getRef()) || !tNodes.contains(rt.getTargetElement().getRef()))
+ throw new BadRequestException("Invalid references to a Node in a Relationship.");
+ if(rt.getSourceElement().getRef() == rt.getTargetElement().getRef())
+ throw new BadRequestException("Source and Target cannot be equal in a Relationship.");
+ relats.add(parseRelationshipTemplate(rt));
+ }
+
+ //Creating TopologyTemplateGrpc object to be sent to server
+ return TopologyTemplateGrpc.newBuilder()
+ .setId("0") //useless value since the server chooses the actual value for the GraphID
+ .addAllNodeTemplate(nodes)
+ .addAllRelationshipTemplate(relats)
+ .build();
+ }
+
+
+ /** Parsing method: TNodeTemplate(tosca) --> NodeTemplateGrpc */
+ private static NodeTemplateGrpc parseNodeTemplate(TNodeTemplate nodeTempl)
+ throws ClassCastException, NullPointerException {
+ Boolean isVerigraphCompl = true;
+ Type type;
+
+ //NodeTemplateGrpc building
+ NodeTemplateGrpc.Builder nodegrpc = NodeTemplateGrpc.newBuilder();
+
+ //ID cannot be null
+ try {
+ nodegrpc.setId(nodeTempl.getId());
+ } catch (NullPointerException ex) {
+ throw new NullPointerException("An ID must be specified for each Node");
+ }
+ //Name can be null
+ try {
+ nodegrpc.setName(nodeTempl.getName());
+ } catch (NullPointerException ex) {
+ nodegrpc.setName("");
+ }
+
+ //Type cannot be null but it can be invalid
+ try {
+ String typestring = nodeTempl.getType().getLocalPart().toLowerCase();
+ type = Type.valueOf(nodeTempl.getType().getLocalPart().toLowerCase().substring(0,typestring.length()-4));
+ } catch (IllegalArgumentException | NullPointerException ex) {
+ //in case the NodeTemplate is not TOSCA-Verigraph compliant, we assume it to be a fieldmodifier node
+ type = Type.fieldmodifier;
+ isVerigraphCompl = false;
+ }
+ nodegrpc.setType(type);
+ ToscaConfigurationGrpc.Builder grpcConfig;
+ if(isVerigraphCompl) {
+ it.polito.tosca.jaxb.Configuration nodeConfig = XmlParsingUtils.obtainConfiguration(nodeTempl);
+ grpcConfig = ToscaConfigurationGrpc.newBuilder();
+ //These fields are optional in TOSCA xml
+ try {
+ grpcConfig.setId(nodeConfig.getConfID());
+ } catch(NullPointerException ex) {
+ grpcConfig.setId(ToscaGrpcUtils.defaultConfID);
+ }
+ try {
+ grpcConfig.setDescription(nodeConfig.getConfDescr());
+ } catch(NullPointerException ex) {
+ grpcConfig.setDescription(ToscaGrpcUtils.defaultDescr);
+ }
+ try {;
+ grpcConfig.setConfiguration(MappingUtils.obtainStringConfiguration(nodeConfig));
+ } catch(NullPointerException | JsonProcessingException ex) {
+ grpcConfig.setConfiguration(ToscaGrpcUtils.defaultConfig);
+ }
+ }
+ else {
+ grpcConfig = ToscaConfigurationGrpc.newBuilder()
+ .setId(ToscaGrpcUtils.defaultConfID)
+ .setDescription(ToscaGrpcUtils.defaultDescr)
+ .setConfiguration(ToscaGrpcUtils.defaultConfig);
+ }
+ nodegrpc.setConfiguration(grpcConfig.build());
+ return nodegrpc.build();
+ }
+
+
+ /** Parsing method: TRelationshipTemplate(tosca) --> RelationshipTemplateGrpc */
+ private static RelationshipTemplateGrpc parseRelationshipTemplate(TRelationshipTemplate relatTempl)
+ throws ClassCastException{
+ String source, target;
+ //RelationshipTemplateGrpc building
+ RelationshipTemplateGrpc.Builder relatgrpc = RelationshipTemplateGrpc.newBuilder();
+
+ //ID and Name can be null
+ try {
+ relatgrpc.setId(relatTempl.getId());
+ } catch (NullPointerException ex) {}//Different Relationship with same ID are considered valid.
+ try {
+ relatgrpc.setName(relatTempl.getName());
+ } catch (NullPointerException ex) {}
+
+ //Source and Target values cannot be null
+ try {
+ TNodeTemplate sourceNode = (TNodeTemplate) relatTempl.getSourceElement().getRef();
+ TNodeTemplate targetNode = (TNodeTemplate) relatTempl.getTargetElement().getRef();
+ source = sourceNode.getId();
+ target = targetNode.getId();
+ } catch (NullPointerException ex) {
+ throw new NullPointerException("Invalid NodeTemplate reference in RelationshipTemplate with id:"
+ + relatTempl.getId());
+ }
+ relatgrpc.setIdSourceNodeTemplate(source)
+ .setIdTargetNodeTemplate(target);
+ return relatgrpc.build();
+ }
+}
diff --git a/verigraph/src/it/polito/verigraph/tosca/converter/grpc/YamlToGrpc.java b/verigraph/src/it/polito/verigraph/tosca/converter/grpc/YamlToGrpc.java new file mode 100644 index 0000000..1a713bd --- /dev/null +++ b/verigraph/src/it/polito/verigraph/tosca/converter/grpc/YamlToGrpc.java @@ -0,0 +1,147 @@ +/*******************************************************************************
+ * Copyright (c) 2018 Politecnico di Torino and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Apache License, Version 2.0
+ * which accompanies this distribution, and is available at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+package it.polito.verigraph.tosca.converter.grpc;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import javax.xml.bind.JAXBException;
+
+import it.polito.verigraph.exception.BadRequestException;
+import it.polito.verigraph.exception.DataNotFoundException;
+import it.polito.verigraph.grpc.NodeTemplateGrpc;
+import it.polito.verigraph.grpc.NodeTemplateGrpc.Type;
+import it.polito.verigraph.grpc.RelationshipTemplateGrpc;
+import it.polito.verigraph.grpc.TopologyTemplateGrpc;
+import it.polito.verigraph.grpc.ToscaConfigurationGrpc;
+import it.polito.verigraph.tosca.YamlParsingUtils;
+import it.polito.verigraph.tosca.yaml.beans.NodeTemplateYaml;
+import it.polito.verigraph.tosca.yaml.beans.RelationshipTemplateYaml;
+import it.polito.verigraph.tosca.yaml.beans.ServiceTemplateYaml;
+
+public class YamlToGrpc {
+
+ /** Returns the (first) TopologyTemplate found in the TOSCA-compliant yaml file */
+ public static TopologyTemplateGrpc obtainTopologyTemplateGrpc (String filepath)
+ throws IOException, JAXBException, DataNotFoundException, ClassCastException, BadRequestException{
+ ServiceTemplateYaml serviceTemplate = YamlParsingUtils.obtainServiceTemplate(filepath);
+
+ //Retrieving of list of NodeTemplate and RelationshipTemplate
+ List<NodeTemplateGrpc> nodes = new ArrayList<NodeTemplateGrpc>();
+ List<RelationshipTemplateGrpc> relats = new ArrayList<RelationshipTemplateGrpc>();
+
+ try {
+ for(Map.Entry<String, NodeTemplateYaml> node : YamlParsingUtils.obtainNodeTemplates(serviceTemplate).entrySet()) {
+ for(NodeTemplateGrpc alreadyAddedNode : nodes)
+ if(alreadyAddedNode.getId().equals(node.getKey()))
+ throw new BadRequestException("The NodeTemplate ID must be unique.");
+ nodes.add(parseNodeTemplate(node));
+ }
+ } catch (NullPointerException e) {
+ throw new BadRequestException("There is not any NodeTemplate in the ServiceTemplate provided.");
+ }
+
+ try {
+ for(Map.Entry<String, RelationshipTemplateYaml> rel : YamlParsingUtils.obtainRelationshipTemplates(serviceTemplate).entrySet()) {
+ relats.add(parseRelationshipTemplate(rel, nodes));
+ }
+ } catch (NullPointerException e) {
+ throw new BadRequestException("There is not any RelationshipTemplate in the ServiceTemplate provided.");
+ }
+
+ //Creating TopologyTemplateGrpc object to be sent to server
+ return TopologyTemplateGrpc.newBuilder()
+ .setId("0") //useless value since the server chooses the actual value for the GraphID
+ .addAllNodeTemplate(nodes)
+ .addAllRelationshipTemplate(relats)
+ .build();
+ }
+
+ /** Parsing method: RelationshipTemplateYaml(tosca) --> RelationshipTemplateGrpc */
+ private static RelationshipTemplateGrpc parseRelationshipTemplate(Entry<String, RelationshipTemplateYaml> rel, List<NodeTemplateGrpc> nodes) throws BadRequestException{
+ String source, target;
+ boolean valid_source = false;
+ boolean valid_target = false;
+
+ //RelationshipTemplateGrpc building
+ RelationshipTemplateGrpc.Builder relatgrpc = RelationshipTemplateGrpc.newBuilder();
+
+ //ID can be null
+ try {
+ relatgrpc.setId(rel.getKey());
+ relatgrpc.setName(rel.getValue().getProperties().get("name"));
+ source = rel.getValue().getProperties().get("source_id");
+ target = rel.getValue().getProperties().get("target_id");
+ } catch (NullPointerException ex) {
+ throw new BadRequestException("Incorrect fields in RelationshipTemplate:" + rel.getKey());
+ }
+
+ //Source and Target values must correctly refer to a NodeTemplate
+ if(source.equals(target))
+ throw new BadRequestException("Source and Target cannot be the same value");
+ for(NodeTemplateGrpc node : nodes) {
+ if(node.getId().equals(source))
+ valid_source = true;
+ if(node.getId().equals(target))
+ valid_target = true;
+ }
+ if(!(valid_source && valid_target))
+ throw new BadRequestException("Invalid NodeTemplate reference in RelationshipTemplate:" + rel.getKey());
+
+ return relatgrpc.setIdSourceNodeTemplate(source).setIdTargetNodeTemplate(target).build();
+
+ }
+
+ /** Parsing method: NodeTemplateYaml(tosca) --> NodeTemplateGrpc */
+ private static NodeTemplateGrpc parseNodeTemplate(Entry<String, NodeTemplateYaml> node)
+ throws ClassCastException, NullPointerException, BadRequestException {
+ Boolean isVerigraphCompl = true;
+ Type type;
+
+ //NodeTemplateGrpc building
+ NodeTemplateGrpc.Builder nodegrpc = NodeTemplateGrpc.newBuilder()
+ .setId(node.getKey());
+
+ try {
+ nodegrpc.setName(node.getValue().getName());
+ } catch (NullPointerException ex) {
+ throw new BadRequestException("Invalid name in a NodeTemplate.");
+ }
+
+ //Type cannot be null but it can be invalid
+ try {
+ type = Type.valueOf(node.getValue().getType().replace("verigraph.nodeTypes.", "").toLowerCase());
+ } catch (IllegalArgumentException | NullPointerException ex) {
+ //in case the NodeTemplate is not TOSCA-Verigraph compliant, we assume it to be a fieldmodifier node
+ type = Type.fieldmodifier;
+ isVerigraphCompl = false;
+ }
+ nodegrpc.setType(type);
+ ToscaConfigurationGrpc.Builder grpcConfig;
+ if(isVerigraphCompl) {
+ String jsonConfig = YamlParsingUtils.obtainConfiguration(node.getValue());
+ grpcConfig = ToscaConfigurationGrpc.newBuilder()
+ .setId("")
+ .setDescription("")
+ .setConfiguration(jsonConfig);
+ }
+ else {
+ grpcConfig = ToscaConfigurationGrpc.newBuilder()
+ .setId(ToscaGrpcUtils.defaultConfID)
+ .setDescription(ToscaGrpcUtils.defaultDescr)
+ .setConfiguration(ToscaGrpcUtils.defaultConfig);
+ }
+ nodegrpc.setConfiguration(grpcConfig.build());
+ return nodegrpc.build();
+ }
+
+}
\ No newline at end of file diff --git a/verigraph/src/it/polito/verigraph/tosca/converter/xml/GraphToXml.java b/verigraph/src/it/polito/verigraph/tosca/converter/xml/GraphToXml.java new file mode 100644 index 0000000..613588f --- /dev/null +++ b/verigraph/src/it/polito/verigraph/tosca/converter/xml/GraphToXml.java @@ -0,0 +1,134 @@ +/*******************************************************************************
+ * Copyright (c) 2018 Politecnico di Torino and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Apache License, Version 2.0
+ * which accompanies this distribution, and is available at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+package it.polito.verigraph.tosca.converter.xml;
+
+import java.io.IOException;
+import java.util.Map;
+
+import javax.xml.namespace.QName;
+
+import it.polito.verigraph.model.Configuration;
+import it.polito.verigraph.model.Graph;
+import it.polito.verigraph.model.Neighbour;
+import it.polito.verigraph.model.Node;
+import it.polito.verigraph.tosca.MappingUtils;
+import it.polito.tosca.jaxb.Definitions;
+import it.polito.tosca.jaxb.TEntityTemplate.Properties;
+import it.polito.tosca.jaxb.TNodeTemplate;
+import it.polito.tosca.jaxb.TRelationshipTemplate;
+import it.polito.tosca.jaxb.TRelationshipTemplate.SourceElement;
+import it.polito.tosca.jaxb.TRelationshipTemplate.TargetElement;
+import it.polito.tosca.jaxb.TServiceTemplate;
+import it.polito.tosca.jaxb.TTopologyTemplate;
+
+public class GraphToXml {
+ /** model --> tosca_xml*/
+
+ public static Definitions mapGraph(Graph graph) {
+ Definitions definitions = new Definitions();
+ TServiceTemplate serviceTemplate = mapPathToXml(graph);
+ definitions.getServiceTemplateOrNodeTypeOrNodeTypeImplementation().add(serviceTemplate);
+
+ return definitions;
+ }
+
+ // These functions have been split so that they can be reused for obtaining all the paths
+ //into a single Definitions (see mapPathsToXml)
+ public static TServiceTemplate mapPathToXml(Graph graph) {
+
+ TServiceTemplate serviceTemplate = new TServiceTemplate();
+ TTopologyTemplate topologyTemplate = new TTopologyTemplate();
+
+ for(Node node : graph.getNodes().values()) {
+ long i = 0;
+ TNodeTemplate nodeTemplate = mapNode(node);
+ topologyTemplate.getNodeTemplateOrRelationshipTemplate().add(nodeTemplate);
+
+ // RelationshipTemplate mapping
+ Map<Long,Neighbour> neighMap = node.getNeighbours();
+ for (Map.Entry<Long, Neighbour> myentry : neighMap.entrySet()) {
+ Neighbour neigh = myentry.getValue();
+ if (graph.getNodes().containsKey(neigh.getId())) {
+ // I have to check that because if I'm mapping a path (and not a graph) I could have
+ //as neighbour a node which is not in the path
+ TRelationshipTemplate relat = mapRelationship(graph, node, neigh, i);
+ topologyTemplate.getNodeTemplateOrRelationshipTemplate().add(relat);
+ i++; //Neighbour does not have a neighbourID! RelationshipTemplate does,
+ //so it is an incremental number for each node
+ }
+ }
+ }
+
+ serviceTemplate.setId(String.valueOf(graph.getId()));
+ serviceTemplate.setTopologyTemplate(topologyTemplate);
+
+ return serviceTemplate;
+ }
+
+
+ private static TNodeTemplate mapNode(Node node){
+ TNodeTemplate nodeTemplate = new TNodeTemplate();
+
+ nodeTemplate.setId(String.valueOf(node.getId()));
+ nodeTemplate.setName(node.getName());
+
+ //QName type = new QName("http://docs.oasis-open.org/tosca/ns/2011/12/ToscaVerigraphDefinition")
+ QName type = new QName("http://docs.oasis-open.org/tosca/ns/2011/12",
+ node.getFunctional_type().substring(0, 1).toUpperCase() + node.
+ getFunctional_type().substring(1) + "Type");
+ nodeTemplate.setType(type);
+
+ it.polito.tosca.jaxb.Configuration config = mapModelConfiguration(node.getConfiguration(),
+ node.getFunctional_type().toLowerCase());
+ //nodeTemplate.getAny().add(config);
+ nodeTemplate.setProperties(new Properties());
+ nodeTemplate.getProperties().setAny(config);
+ return nodeTemplate;
+ }
+
+
+ private static TRelationshipTemplate mapRelationship(Graph graph, Node sourceNode, Neighbour neigh, long i) {
+ TRelationshipTemplate relationship = new TRelationshipTemplate();
+ SourceElement source = new SourceElement();
+ TargetElement target = new TargetElement();
+
+ Node targetNode = graph.getNodes().get(neigh.getId());
+
+ TNodeTemplate sourceNT = mapNode(sourceNode);
+ TNodeTemplate targetNT = mapNode(targetNode);
+
+ source.setRef(sourceNT);
+ target.setRef(targetNT);
+
+ relationship.setId(String.valueOf(i));
+ relationship.setSourceElement(source);
+ relationship.setTargetElement(target);
+ relationship.setName(sourceNode.getName()+"to"+neigh.getName());
+
+ return relationship;
+ }
+
+
+ private static it.polito.tosca.jaxb.Configuration mapModelConfiguration(Configuration conf, String type) {
+ it.polito.tosca.jaxb.Configuration configuration = new it.polito.tosca.jaxb.Configuration();
+ try {
+ //We are passing the configuration type to the Deserializer context
+ configuration = MappingUtils.obtainToscaConfiguration(conf, type);
+
+ //In Graph, ID and DESCRIPTION are always empty
+ //configuration.setConfID(conf.getId());
+ //configuration.setConfDescr(conf.getDescription());
+
+ } catch (IOException | NullPointerException e) {
+ e.printStackTrace();
+ }
+ return configuration;
+ }
+
+}
diff --git a/verigraph/src/it/polito/verigraph/tosca/converter/xml/XmlToGraph.java b/verigraph/src/it/polito/verigraph/tosca/converter/xml/XmlToGraph.java new file mode 100644 index 0000000..3744ba2 --- /dev/null +++ b/verigraph/src/it/polito/verigraph/tosca/converter/xml/XmlToGraph.java @@ -0,0 +1,167 @@ +/*******************************************************************************
+ * Copyright (c) 2018 Politecnico di Torino and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Apache License, Version 2.0
+ * which accompanies this distribution, and is available at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+package it.polito.verigraph.tosca.converter.xml;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+import it.polito.verigraph.exception.BadRequestException;
+import it.polito.verigraph.exception.DataNotFoundException;
+import it.polito.verigraph.model.Configuration;
+import it.polito.verigraph.model.Graph;
+import it.polito.verigraph.model.Neighbour;
+import it.polito.verigraph.model.Node;
+import it.polito.verigraph.tosca.MappingUtils;
+import it.polito.verigraph.tosca.XmlParsingUtils;
+import it.polito.tosca.jaxb.Definitions;
+import it.polito.tosca.jaxb.TExtensibleElements;
+import it.polito.tosca.jaxb.TNodeTemplate;
+import it.polito.tosca.jaxb.TRelationshipTemplate;
+import it.polito.tosca.jaxb.TServiceTemplate;
+
+public class XmlToGraph {
+ public static Graph mapTopologyTemplate(Definitions definitions) throws DataNotFoundException, BadRequestException {
+ Graph graph = new Graph();
+ Map<Long, Node> nodes = new HashMap<>();
+
+ List<TExtensibleElements> elements = definitions.getServiceTemplateOrNodeTypeOrNodeTypeImplementation();
+
+ // Retrieve the list of ServiceTemplate in Definitions
+ List<TServiceTemplate> serviceTemplates = elements.stream().filter(p -> p instanceof TServiceTemplate)
+ .map(obj -> (TServiceTemplate) obj).collect(Collectors.toList());
+ if (serviceTemplates.isEmpty())
+ throw new DataNotFoundException("There is no ServiceTemplate into the Definitions object");
+
+ List<TNodeTemplate> nodeTemplates = XmlParsingUtils.obtainNodeTemplates(serviceTemplates.get(0));
+
+ for (TNodeTemplate nodeTemplate : nodeTemplates) {
+ Node node = mapNodeTemplate(nodeTemplate);
+ nodes.put(Long.valueOf(nodeTemplate.getId()), node);
+ }
+
+ // Add Neighbour to the Node of the list
+ List<TRelationshipTemplate> relationshipTemplates = XmlParsingUtils.obtainRelationshipTemplates(serviceTemplates.get(0));
+ mapRelationshipTemplates(nodes, relationshipTemplates);
+
+ // Add Nodes and ID to the graph
+ graph.setNodes(nodes);
+
+ try {
+ graph.setId(Long.valueOf(serviceTemplates.get(0).getId()));
+ } catch (NumberFormatException ex) {
+ throw new BadRequestException("If you want to store your TopologyTemplate on this server, "
+ + "the TopologyTemplate ID must be a number.");
+ }
+
+ return graph;
+ }
+
+
+ private static Node mapNodeTemplate(TNodeTemplate nodeTemplate) {
+ Node node = new Node();
+
+ String toscaType = nodeTemplate.getType().toString();
+ toscaType = toscaType.replace("Type", "").replace("{http://docs.oasis-open.org/tosca/ns/2011/12}", "");
+ toscaType = toscaType.toLowerCase();
+
+ try {
+ node.setId(Long.valueOf(nodeTemplate.getId()));
+ } catch(NumberFormatException ex) {
+ throw new BadRequestException("The NodeTemplate ID must be a number.");
+ }
+ try {
+ node.setName(nodeTemplate.getName());
+ Configuration conf = mapToscaConfiguration(XmlParsingUtils.obtainConfiguration(nodeTemplate));
+ node.setConfiguration(conf);
+ node.setFunctional_type(toscaType);
+ } catch(NullPointerException | IOException ex) {
+ throw new BadRequestException("The NodeTemplate id:"+node.getId()+" has wrong fields representation.");
+ }
+ return node;
+ }
+
+
+ private static void mapRelationshipTemplates(Map<Long, Node> nodes, List<TRelationshipTemplate> relationshipTemplates) {
+ //update of nodes... (update = Node + its Neighbours)
+ for(TRelationshipTemplate relationshipTemplate : relationshipTemplates) {
+ if (relationshipTemplate != null) {
+ try {
+ if(relationshipTemplate.getSourceElement().getRef() == relationshipTemplate.getTargetElement().getRef())
+ throw new BadRequestException("Source and Target cannot be equal in a Relationship.");
+
+ // Retrieve the target Node name and generate a new Neighbour
+ TNodeTemplate targetNodeTemplate = (TNodeTemplate) relationshipTemplate.getTargetElement().getRef();
+ String neighName = nodes.get(Long.valueOf(targetNodeTemplate.getId())).getName();
+ //this manages invalid/inexistent node ID for target node
+ Neighbour neigh = new Neighbour();
+ neigh.setName(neighName);
+ neigh.setId(Long.valueOf(relationshipTemplate.getId()));
+
+ //Retrieve the Neighbour map of the source Node and add the Neighbour
+ TNodeTemplate sourceNodeTemplate = (TNodeTemplate) relationshipTemplate.getSourceElement().getRef();
+ Node source = nodes.get(Long.valueOf(sourceNodeTemplate.getId()));
+ //this manages invalid/inexistent node ID for source node
+ Map<Long,Neighbour> sourceNodeNeighMap = source.getNeighbours();
+ if(sourceNodeNeighMap.containsKey(neigh.getId()))
+ throw new BadRequestException("The RelationshipTemplate ID must be unique.");
+ else
+ sourceNodeNeighMap.put(neigh.getId(), neigh);
+ source.setNeighbours(sourceNodeNeighMap);
+
+ //Update the Node list
+ nodes.put(Long.valueOf(sourceNodeTemplate.getId()), source);
+ } catch(NullPointerException | NumberFormatException ex) {
+ throw new BadRequestException("A RelationshipTemplate has wrong fields representation.");
+ }
+ }
+ }
+ }
+
+ private static Configuration mapToscaConfiguration(it.polito.tosca.jaxb.Configuration configuration)
+ throws JsonProcessingException, IOException {
+ Configuration conf = new Configuration();
+ ObjectMapper mapper = new ObjectMapper();
+ String stringConfiguration;
+
+ //Retrieve configuration ID (optional)
+ if (configuration.getConfID() != null)
+ conf.setId(configuration.getConfID());
+ else
+ conf.setId("");
+
+ //Retrieve description (optional)
+ if (configuration.getConfDescr() != null)
+ conf.setDescription(configuration.getConfDescr());
+ else
+ conf.setDescription("");
+
+ //Retrieve string of configuration
+ try {
+ stringConfiguration = MappingUtils.obtainStringConfiguration(configuration);
+ } catch(IOException ex) {
+ conf.setConfiguration(mapper.readTree("[]"));
+ System.out.println("[WARNING] Provided default configuration.");
+ return conf;
+ }
+
+ //Retrieve JsonNode from the string of configuration
+ try {
+ conf.setConfiguration(mapper.readTree(stringConfiguration));
+ return conf;
+ } catch (IOException e) {
+ throw new BadRequestException("NodeTemplate configuration is invalid.");
+ }
+ }
+}
diff --git a/verigraph/src/it/polito/verigraph/tosca/converter/yaml/GraphToYaml.java b/verigraph/src/it/polito/verigraph/tosca/converter/yaml/GraphToYaml.java new file mode 100644 index 0000000..8766ac5 --- /dev/null +++ b/verigraph/src/it/polito/verigraph/tosca/converter/yaml/GraphToYaml.java @@ -0,0 +1,270 @@ +/*******************************************************************************
+ * Copyright (c) 2018 Politecnico di Torino and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Apache License, Version 2.0
+ * which accompanies this distribution, and is available at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+package it.polito.verigraph.tosca.converter.yaml;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+import com.fasterxml.jackson.core.JsonParseException;
+import com.fasterxml.jackson.databind.InjectableValues;
+import com.fasterxml.jackson.databind.JsonMappingException;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.module.SimpleModule;
+import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
+
+import it.polito.neo4j.jaxb.FunctionalTypes;
+import it.polito.verigraph.exception.BadRequestException;
+import it.polito.verigraph.model.Graph;
+import it.polito.verigraph.model.Neighbour;
+import it.polito.verigraph.model.Node;
+import it.polito.verigraph.tosca.deserializer.YamlConfigurationDeserializer;
+import it.polito.verigraph.tosca.yaml.beans.AntispamConfigurationYaml;
+import it.polito.verigraph.tosca.yaml.beans.AntispamNode;
+import it.polito.verigraph.tosca.yaml.beans.CacheConfigurationYaml;
+import it.polito.verigraph.tosca.yaml.beans.CacheNode;
+import it.polito.verigraph.tosca.yaml.beans.ConfigurationYaml;
+import it.polito.verigraph.tosca.yaml.beans.DpiConfigurationYaml;
+import it.polito.verigraph.tosca.yaml.beans.DpiNode;
+import it.polito.verigraph.tosca.yaml.beans.EndhostConfigurationYaml;
+import it.polito.verigraph.tosca.yaml.beans.EndhostNode;
+import it.polito.verigraph.tosca.yaml.beans.EndpointConfigurationYaml;
+import it.polito.verigraph.tosca.yaml.beans.EndpointNode;
+import it.polito.verigraph.tosca.yaml.beans.FieldModifierConfigurationYaml;
+import it.polito.verigraph.tosca.yaml.beans.FieldModifierNode;
+import it.polito.verigraph.tosca.yaml.beans.FirewallConfigurationYaml;
+import it.polito.verigraph.tosca.yaml.beans.FirewallNode;
+import it.polito.verigraph.tosca.yaml.beans.MailClientConfigurationYaml;
+import it.polito.verigraph.tosca.yaml.beans.MailClientNode;
+import it.polito.verigraph.tosca.yaml.beans.MailServerConfigurationYaml;
+import it.polito.verigraph.tosca.yaml.beans.MailServerNode;
+import it.polito.verigraph.tosca.yaml.beans.NatConfigurationYaml;
+import it.polito.verigraph.tosca.yaml.beans.NatNode;
+import it.polito.verigraph.tosca.yaml.beans.NodeTemplateYaml;
+import it.polito.verigraph.tosca.yaml.beans.RelationshipTemplateYaml;
+import it.polito.verigraph.tosca.yaml.beans.ServiceTemplateYaml;
+import it.polito.verigraph.tosca.yaml.beans.TopologyTemplateYaml;
+import it.polito.verigraph.tosca.yaml.beans.VpnAccessConfigurationYaml;
+import it.polito.verigraph.tosca.yaml.beans.VpnAccessNode;
+import it.polito.verigraph.tosca.yaml.beans.VpnExitConfigurationYaml;
+import it.polito.verigraph.tosca.yaml.beans.VpnExitNode;
+import it.polito.verigraph.tosca.yaml.beans.WebClientConfigurationYaml;
+import it.polito.verigraph.tosca.yaml.beans.WebClientNode;
+import it.polito.verigraph.tosca.yaml.beans.WebServerConfigurationYaml;
+import it.polito.verigraph.tosca.yaml.beans.WebServerNode;
+
+public class GraphToYaml {
+ public static ServiceTemplateYaml mapGraphYaml(Graph graph) {
+ ServiceTemplateYaml serviceTemplate = new ServiceTemplateYaml();
+ TopologyTemplateYaml topologyTemplate = new TopologyTemplateYaml();
+
+ topologyTemplate.setNode_templates(new HashMap<String,NodeTemplateYaml>());
+ topologyTemplate.setRelationship_templates(new HashMap<String,RelationshipTemplateYaml>());
+ serviceTemplate.setMetadata(new HashMap<String,String>());
+
+ //Neighbour does not have a neighbourID!
+ //RelationshipTemplate does, so it is an incremental number for each node
+ long i = 0; //This counter will act as a fake incremental id of relationships
+ for(Node node : graph.getNodes().values()) {
+ NodeTemplateYaml nodeTemplate;
+ try {
+ nodeTemplate = mapNodeYaml(node);
+ } catch (IOException e) {
+ throw new BadRequestException("Error while mapping a Node in Yaml object.");
+ }
+ topologyTemplate.getNode_templates().put(String.valueOf(node.getId()), nodeTemplate);
+ //shall we catch NumberFormatException?
+
+ Map<Long,Neighbour> neighMap = node.getNeighbours();
+ for (Map.Entry<Long, Neighbour> myentry : neighMap.entrySet()) {
+ Neighbour neigh = myentry.getValue();
+ if (graph.getNodes().containsKey(neigh.getId())) {
+ // I have to check that because if I'm mapping a path (and not a graph)
+ //I could have as neighbour a node which is not in the path
+ RelationshipTemplateYaml relat = mapRelationshipYaml(node, neigh);
+ topologyTemplate.getRelationship_templates().put(String.valueOf(i), relat);
+ i++;
+ }
+ }
+ }
+
+ serviceTemplate.getMetadata().put("template_id", String.valueOf(graph.getId()));
+ serviceTemplate.setTopology_template(topologyTemplate);
+ return serviceTemplate;
+ }
+
+
+ private static NodeTemplateYaml mapNodeYaml(Node node) throws JsonParseException, JsonMappingException, IOException {
+
+ ObjectMapper mapper = new ObjectMapper(new YAMLFactory());
+ JsonNode configNode = node.getConfiguration().getConfiguration();
+ SimpleModule module = new SimpleModule();
+
+ //Passing the configuration type to the Deserializer context
+ module.addDeserializer(ConfigurationYaml.class, new YamlConfigurationDeserializer());
+ mapper.registerModule(module);
+
+ //Here we use the custom deserializer to convert the JsonNode into a Yaml bean
+ //The injectable value allows to provide an additional info to the deserializer that will be able to
+ //know that it is parsing a certain type of Configuration.
+ ConfigurationYaml yamlConfig = mapper
+ .reader(new InjectableValues.Std().addValue("type", node.getFunctional_type().toLowerCase()))
+ .forType(ConfigurationYaml.class).readValue(configNode);
+
+ FunctionalTypes nodeType = FunctionalTypes.valueOf(node.getFunctional_type().toUpperCase());
+ switch(nodeType) {
+ case ANTISPAM:
+ AntispamNode antispamNode = new AntispamNode();
+ antispamNode.setName(node.getName());
+ antispamNode.setType("verigraph.nodeTypes." +
+ node.getFunctional_type().substring(0, 1).toUpperCase() +
+ node.getFunctional_type().substring(1));
+ antispamNode.setProperties((AntispamConfigurationYaml) yamlConfig);
+ return antispamNode;
+
+ case CACHE:
+ CacheNode cacheNode = new CacheNode();
+ cacheNode.setName(node.getName());
+ cacheNode.setType("verigraph.nodeTypes." +
+ node.getFunctional_type().substring(0, 1).toUpperCase() +
+ node.getFunctional_type().substring(1));
+ cacheNode.setProperties((CacheConfigurationYaml) yamlConfig);
+ return cacheNode;
+
+ case DPI:
+ DpiNode dpiNode = new DpiNode();
+ dpiNode.setName(node.getName());
+ dpiNode.setType("verigraph.nodeTypes." +
+ node.getFunctional_type().substring(0, 1).toUpperCase() +
+ node.getFunctional_type().substring(1));
+ dpiNode.setProperties((DpiConfigurationYaml) yamlConfig);
+ return dpiNode;
+
+ case ENDHOST:
+ EndhostNode endhostNode = new EndhostNode();
+ endhostNode.setName(node.getName());
+ endhostNode.setType("verigraph.nodeTypes." +
+ node.getFunctional_type().substring(0, 1).toUpperCase() +
+ node.getFunctional_type().substring(1));
+ endhostNode.setProperties((EndhostConfigurationYaml) yamlConfig);
+ return endhostNode;
+
+ case ENDPOINT:
+ EndpointNode endpointNode = new EndpointNode();
+ endpointNode.setName(node.getName());
+ endpointNode.setType("verigraph.nodeTypes." +
+ node.getFunctional_type().substring(0, 1).toUpperCase() +
+ node.getFunctional_type().substring(1));
+ endpointNode.setProperties((EndpointConfigurationYaml) yamlConfig);
+ return endpointNode;
+
+ case FIELDMODIFIER:
+ FieldModifierNode fieldmodifierNode = new FieldModifierNode();
+ fieldmodifierNode.setName(node.getName());
+ fieldmodifierNode.setType("verigraph.nodeTypes." +
+ node.getFunctional_type().substring(0, 1).toUpperCase() +
+ node.getFunctional_type().substring(1));
+ fieldmodifierNode.setProperties((FieldModifierConfigurationYaml) yamlConfig);
+ return fieldmodifierNode;
+
+ case FIREWALL:
+ FirewallNode firewallNode = new FirewallNode();
+ firewallNode.setName(node.getName());
+ firewallNode.setType("verigraph.nodeTypes." +
+ node.getFunctional_type().substring(0, 1).toUpperCase() +
+ node.getFunctional_type().substring(1));
+ firewallNode.setProperties((FirewallConfigurationYaml) yamlConfig);
+ return firewallNode;
+
+ case MAILCLIENT:
+ MailClientNode mailclientNode = new MailClientNode();
+ mailclientNode.setName(node.getName());
+ mailclientNode.setType("verigraph.nodeTypes." +
+ node.getFunctional_type().substring(0, 1).toUpperCase() +
+ node.getFunctional_type().substring(1));
+ mailclientNode.setProperties((MailClientConfigurationYaml) yamlConfig);
+ return mailclientNode;
+
+ case MAILSERVER:
+ MailServerNode mailserverNode = new MailServerNode();
+ mailserverNode.setName(node.getName());
+ mailserverNode.setType("verigraph.nodeTypes." +
+ node.getFunctional_type().substring(0, 1).toUpperCase() +
+ node.getFunctional_type().substring(1));
+ mailserverNode.setProperties((MailServerConfigurationYaml) yamlConfig);
+ return mailserverNode;
+
+ case NAT:
+ NatNode natNode = new NatNode();
+ natNode.setName(node.getName());
+ natNode.setType("verigraph.nodeTypes." +
+ node.getFunctional_type().substring(0, 1).toUpperCase() +
+ node.getFunctional_type().substring(1));
+ natNode.setProperties((NatConfigurationYaml) yamlConfig);
+ return natNode;
+
+ case VPNACCESS:
+ VpnAccessNode vpnaccessNode = new VpnAccessNode();
+ vpnaccessNode.setName(node.getName());
+ vpnaccessNode.setType("verigraph.nodeTypes." +
+ node.getFunctional_type().substring(0, 1).toUpperCase() +
+ node.getFunctional_type().substring(1));
+ vpnaccessNode.setProperties((VpnAccessConfigurationYaml) yamlConfig);
+ return vpnaccessNode;
+
+ case VPNEXIT:
+ VpnExitNode vpnexitNode = new VpnExitNode();
+ vpnexitNode.setName(node.getName());
+ vpnexitNode.setType("verigraph.nodeTypes." +
+ node.getFunctional_type().substring(0, 1).toUpperCase() +
+ node.getFunctional_type().substring(1));
+ vpnexitNode.setProperties((VpnExitConfigurationYaml) yamlConfig);
+ return vpnexitNode;
+
+ case WEBCLIENT:
+ WebClientNode webclientNode = new WebClientNode();
+ webclientNode.setName(node.getName());
+ webclientNode.setType("verigraph.nodeTypes." +
+ node.getFunctional_type().substring(0, 1).toUpperCase() +
+ node.getFunctional_type().substring(1));
+ webclientNode.setProperties((WebClientConfigurationYaml) yamlConfig);
+ return webclientNode;
+
+ case WEBSERVER:
+ WebServerNode webserverNode = new WebServerNode();
+ webserverNode.setName(node.getName());
+ webserverNode.setType("verigraph.nodeTypes." +
+ node.getFunctional_type().substring(0, 1).toUpperCase() +
+ node.getFunctional_type().substring(1));
+ webserverNode.setProperties((WebServerConfigurationYaml) yamlConfig);
+ return webserverNode;
+
+ default:
+ FieldModifierNode defaultNode = new FieldModifierNode();
+ defaultNode.setName(node.getName());
+ defaultNode.setType("verigraph.nodeTypes.Fieldmodifier");
+ defaultNode.setProperties(new FieldModifierConfigurationYaml());
+ return defaultNode;
+ }
+
+ }
+
+ private static RelationshipTemplateYaml mapRelationshipYaml(Node sourceNode, Neighbour neigh) {
+ RelationshipTemplateYaml relationship = new RelationshipTemplateYaml();
+ relationship.setProperties(new HashMap<String,String>());
+
+ relationship.setType("verigraph.relationshipType.generic");
+ relationship.getProperties().put("source_id", String.valueOf(sourceNode.getId())); //to be catched?
+ relationship.getProperties().put("target_id", String.valueOf(neigh.getId()));
+ relationship.getProperties().put("name", sourceNode.getName()+"to"+neigh.getName());
+
+ return relationship;
+ }
+}
diff --git a/verigraph/src/it/polito/verigraph/tosca/converter/yaml/YamlToGraph.java b/verigraph/src/it/polito/verigraph/tosca/converter/yaml/YamlToGraph.java new file mode 100644 index 0000000..3922cf6 --- /dev/null +++ b/verigraph/src/it/polito/verigraph/tosca/converter/yaml/YamlToGraph.java @@ -0,0 +1,138 @@ +/*******************************************************************************
+ * Copyright (c) 2018 Politecnico di Torino and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Apache License, Version 2.0
+ * which accompanies this distribution, and is available at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+package it.polito.verigraph.tosca.converter.yaml;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.module.SimpleModule;
+
+import it.polito.verigraph.exception.BadRequestException;
+import it.polito.verigraph.model.Configuration;
+import it.polito.verigraph.model.Graph;
+import it.polito.verigraph.model.Neighbour;
+import it.polito.verigraph.model.Node;
+import it.polito.verigraph.tosca.YamlParsingUtils;
+import it.polito.verigraph.tosca.serializer.YamlConfigSerializer;
+import it.polito.verigraph.tosca.yaml.beans.ConfigurationYaml;
+import it.polito.verigraph.tosca.yaml.beans.NodeTemplateYaml;
+import it.polito.verigraph.tosca.yaml.beans.RelationshipTemplateYaml;
+import it.polito.verigraph.tosca.yaml.beans.ServiceTemplateYaml;
+
+public class YamlToGraph {
+ public static Graph mapTopologyTemplateYaml(ServiceTemplateYaml yamlServiceTemplate) throws BadRequestException {
+ Graph graph = new Graph();
+ Map<Long, Node> graphNodes = new HashMap<>();
+ Map<String, NodeTemplateYaml> nodes = new HashMap<>();
+ Map<String, RelationshipTemplateYaml> relats = new HashMap<>();
+
+ nodes = yamlServiceTemplate.getTopology_template().getNode_templates();
+
+ for (Map.Entry<String, NodeTemplateYaml> nodeYamlEntry : nodes.entrySet()) {
+ Node node = mapNodeTemplateYaml(nodeYamlEntry.getValue());
+
+ try {
+ graphNodes.put(Long.valueOf(nodeYamlEntry.getKey()), node);
+ } catch (NumberFormatException e) {
+ throw new BadRequestException("The NodeTemplate ID must be a number.");
+ }
+
+ }
+
+ // Add Neighbours to the Nodes of the list
+ relats = yamlServiceTemplate.getTopology_template().getRelationship_templates();
+ mapRelationshipTemplatesYaml(graphNodes, relats);
+
+ // Add Nodes and ID to the graph
+ graph.setNodes(graphNodes);
+ try {
+ graph.setId(Long.valueOf(yamlServiceTemplate.getMetadata().get("template_id")));
+ } catch (NumberFormatException ex) {
+ throw new BadRequestException("If you want to use this service, the TopologyTemplate ID must be a number.");
+ } catch (NullPointerException ex) {} //ID is not mandatory for the user since VeriGraph provides its IDs
+
+ return graph;
+ }
+
+
+ private static Node mapNodeTemplateYaml(NodeTemplateYaml yamlNodeTemplate) {
+ Node node = new Node();
+
+ String type = yamlNodeTemplate.getType().replace("verigraph.nodeTypes.", "").toLowerCase();
+
+ try {
+ node.setName(yamlNodeTemplate.getName());
+ Configuration conf = mapConfigurationYaml(yamlNodeTemplate);
+ node.setConfiguration(conf);
+ node.setFunctional_type(type);
+ } catch(NullPointerException ex) {
+ throw new BadRequestException("A NodeTemplate has wrong fields representation.");
+ }
+ return node;
+ }
+
+
+ private static void mapRelationshipTemplatesYaml(Map<Long, Node> graphNodes, Map<String, RelationshipTemplateYaml> relats) {
+ //updated nodes (update = Node + its Neighbours)
+ for(Map.Entry<String, RelationshipTemplateYaml> yamlRelationshipTemplate : relats.entrySet()) {
+ try {
+ // Retrieve relationship information
+ String target = yamlRelationshipTemplate.getValue().getProperties().get("target_id");
+ String source = yamlRelationshipTemplate.getValue().getProperties().get("source_id");
+ String name = graphNodes.get(Long.valueOf(target)).getName();
+
+ Neighbour neigh = new Neighbour();
+ neigh.setName(name);
+ neigh.setId(Long.valueOf(target));
+
+ //Retrieve the Neighbour map of the source Node and add the Neighbour
+ Node sourceNode = graphNodes.get(Long.valueOf(source));
+ Map<Long,Neighbour> sourceNodeNeighMap = sourceNode.getNeighbours();
+ if(sourceNodeNeighMap.containsKey(neigh.getId()))
+ throw new BadRequestException("The RelationshipTemplate ID must be unique.");
+ else
+ sourceNodeNeighMap.put(neigh.getId(), neigh);
+ sourceNode.setNeighbours(sourceNodeNeighMap);
+
+ //Update the Node list
+ graphNodes.put(Long.valueOf(source), sourceNode);
+
+ } catch(NullPointerException | NumberFormatException ex) {
+ throw new BadRequestException("A RelationshipTemplate has wrong fields representation.");
+ }
+
+ }
+
+ }
+
+
+ private static Configuration mapConfigurationYaml(NodeTemplateYaml node) {
+ Configuration config = new Configuration();
+ JsonNode jsonConfiguration = null;
+ ObjectMapper mapper = new ObjectMapper();
+ SimpleModule module = new SimpleModule();
+ module.addSerializer(ConfigurationYaml.class, new YamlConfigSerializer());
+ mapper.registerModule(module);
+
+ try{
+ String stringConfiguration = YamlParsingUtils.obtainConfiguration(node);
+ jsonConfiguration = mapper.readTree(stringConfiguration);
+ config.setConfiguration(jsonConfiguration);
+ config.setDescription("");
+ config.setId("");
+ } catch (NullPointerException | IOException | BadRequestException e) {
+ throw new BadRequestException("Not able to retrieve a valid configuration");
+ }
+
+ return config;
+ }
+}
diff --git a/verigraph/src/it/polito/verigraph/tosca/deserializer/XmlConfigurationDeserializer.java b/verigraph/src/it/polito/verigraph/tosca/deserializer/XmlConfigurationDeserializer.java new file mode 100644 index 0000000..7e2ee4d --- /dev/null +++ b/verigraph/src/it/polito/verigraph/tosca/deserializer/XmlConfigurationDeserializer.java @@ -0,0 +1,177 @@ +/*******************************************************************************
+ * Copyright (c) 2018 Politecnico di Torino and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Apache License, Version 2.0
+ * which accompanies this distribution, and is available at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+package it.polito.verigraph.tosca.deserializer;
+
+import it.polito.tosca.jaxb.Configuration;
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.core.ObjectCodec;
+import com.fasterxml.jackson.databind.DeserializationContext;
+import com.fasterxml.jackson.databind.JsonDeserializer;
+import com.fasterxml.jackson.databind.JsonNode;
+import java.io.IOException;
+import java.math.BigInteger;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+public class XmlConfigurationDeserializer extends JsonDeserializer<Configuration> {
+
+ @Override
+ public Configuration deserialize(JsonParser jp, DeserializationContext ctxt)
+ throws IOException, JsonProcessingException {
+ ObjectCodec oc = jp.getCodec();
+ JsonNode node = oc.readTree(jp);
+ Configuration deserialized;
+
+ try {
+ //Get the content from the array wrapping the JSON configuration
+ final Iterator<JsonNode> elements = node.elements();
+ deserialized = new Configuration();
+
+
+ if(!elements.hasNext()) {
+ //System.out.println("The provided configuration is empty.");
+ //return null; //TODO shall we return an empty configuration?
+
+ return new Configuration();
+ }
+
+ switch ((String) ctxt.findInjectableValue("type", null, null)) {
+
+ case "antispam":
+ Configuration.AntispamConfiguration antispam = new Configuration.AntispamConfiguration();
+ List<String> sources = antispam.getSource();
+ while (elements.hasNext()) {
+ sources.add(elements.next().asText());
+ }
+ deserialized.setAntispamConfiguration(antispam);
+ break;
+
+ case "cache":
+ Configuration.CacheConfiguration cache = new Configuration.CacheConfiguration();
+ List<String> resources = cache.getResource();
+ while(elements.hasNext()) {
+ resources.add(elements.next().asText());
+ }
+ deserialized.setCacheConfiguration(cache);
+ break;
+
+ case "endhost":
+ Configuration.EndhostConfiguration endhost = new Configuration.EndhostConfiguration();
+ JsonNode thisnode = elements.next();
+
+ if(thisnode.has("body"))
+ endhost.setBody(thisnode.findValue("body").asText());
+ if(thisnode.has("sequence"))
+ endhost.setSequence(BigInteger.valueOf(Long.valueOf(thisnode.findValue("sequence").asText())));
+ if(thisnode.has("protocol"))
+ endhost.setProtocol(thisnode.findValue("protocol").asText());
+ if(thisnode.has("email_from"))
+ endhost.setEmailFrom(thisnode.findValue("email_from").asText());
+ if(thisnode.has("url"))
+ endhost.setUrl(thisnode.findValue("url").asText());
+ if(thisnode.has("options"))
+ endhost.setOptions(thisnode.findValue("options").asText());
+ if(thisnode.has("destination"))
+ endhost.setDestination(thisnode.findValue("destination").asText());
+
+ deserialized.setEndhostConfiguration(endhost);
+ break;
+
+ case "endpoint":
+ Configuration.EndpointConfiguration endpoint = new Configuration.EndpointConfiguration();
+ deserialized.setEndpointConfiguration(endpoint);
+ break;
+
+ case "fieldmodifier":
+ Configuration.FieldmodifierConfiguration fieldmodifier = new Configuration.FieldmodifierConfiguration();
+ deserialized.setFieldmodifierConfiguration(fieldmodifier);
+ break;
+
+ case "firewall":
+ Configuration.FirewallConfiguration firewall = new Configuration.FirewallConfiguration();
+ List<Configuration.FirewallConfiguration.Elements> fwelements = firewall.getElements();
+ Configuration.FirewallConfiguration.Elements element;
+
+ Iterator<Map.Entry<String, JsonNode>> current = elements.next().fields();
+ Map.Entry<String, JsonNode> entry;
+ while(current.hasNext()) {
+ entry = current.next();
+ element = new Configuration.FirewallConfiguration.Elements();
+ element.setSource(entry.getKey());
+ element.setDestination(entry.getValue().asText());
+ fwelements.add(element);
+ }
+
+ deserialized.setFirewallConfiguration(firewall);
+ break;
+
+ case "mailclient":
+ Configuration.MailclientConfiguration mailclient = new Configuration.MailclientConfiguration();
+ mailclient.setMailserver(elements.next().findValue("mailserver").asText());
+ deserialized.setMailclientConfiguration(mailclient);
+ break;
+
+ case "mailserver":
+ Configuration.MailserverConfiguration mailserver = new Configuration.MailserverConfiguration();
+ deserialized.setMailserverConfiguration(mailserver);
+ break;
+
+ case "nat":
+ Configuration.NatConfiguration nat = new Configuration.NatConfiguration();
+ List<String> natsource = nat.getSource();
+ while(elements.hasNext()) {
+ natsource.add(elements.next().asText());
+ }
+ deserialized.setNatConfiguration(nat);
+ break;
+
+ case "vpnaccess":
+ Configuration.VpnaccessConfiguration vpnaccess = new Configuration.VpnaccessConfiguration();
+ vpnaccess.setVpnexit(elements.next().findValue("vpnexit").asText());
+ deserialized.setVpnaccessConfiguration(vpnaccess);
+ break;
+
+ case "vpnexit":
+ Configuration.VpnexitConfiguration vpnexit = new Configuration.VpnexitConfiguration();
+ vpnexit.setVpnaccess(elements.next().findValue("vpnaccess").asText());
+ deserialized.setVpnexitConfiguration(vpnexit);
+ break;
+
+ case "webclient":
+ Configuration.WebclientConfiguration webclient = new Configuration.WebclientConfiguration();
+ webclient.setNameWebServer(elements.next().findValue("webserver").asText());
+ deserialized.setWebclientConfiguration(webclient);
+ break;
+
+ case "webserver":
+ Configuration.WebserverConfiguration webserver = new Configuration.WebserverConfiguration();
+ deserialized.setWebserverConfiguration(webserver);
+ break;
+
+ default:
+ Configuration.FieldmodifierConfiguration defaultForwarder = new Configuration.FieldmodifierConfiguration();
+ deserialized.setFieldmodifierConfiguration(defaultForwarder);
+ break;
+ }
+
+
+ } catch (Exception e) {
+ // TODO Auto-generated catch block
+ System.err.println("Error converting the Json to XmlConfiguration");
+ e.printStackTrace();
+ return null;
+ }
+
+ return deserialized;
+
+ }
+
+}
diff --git a/verigraph/src/it/polito/verigraph/tosca/deserializer/YamlConfigurationDeserializer.java b/verigraph/src/it/polito/verigraph/tosca/deserializer/YamlConfigurationDeserializer.java new file mode 100644 index 0000000..8fb7e52 --- /dev/null +++ b/verigraph/src/it/polito/verigraph/tosca/deserializer/YamlConfigurationDeserializer.java @@ -0,0 +1,251 @@ +/*******************************************************************************
+ * Copyright (c) 2018 Politecnico di Torino and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Apache License, Version 2.0
+ * which accompanies this distribution, and is available at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+package it.polito.verigraph.tosca.deserializer;
+
+
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.core.ObjectCodec;
+import com.fasterxml.jackson.databind.DeserializationContext;
+import com.fasterxml.jackson.databind.JsonDeserializer;
+import com.fasterxml.jackson.databind.JsonNode;
+
+import it.polito.verigraph.tosca.yaml.beans.AntispamConfigurationYaml;
+import it.polito.verigraph.tosca.yaml.beans.CacheConfigurationYaml;
+import it.polito.verigraph.tosca.yaml.beans.ConfigurationYaml;
+import it.polito.verigraph.tosca.yaml.beans.DpiConfigurationYaml;
+import it.polito.verigraph.tosca.yaml.beans.EndhostConfigurationYaml;
+import it.polito.verigraph.tosca.yaml.beans.EndpointConfigurationYaml;
+import it.polito.verigraph.tosca.yaml.beans.FieldModifierConfigurationYaml;
+import it.polito.verigraph.tosca.yaml.beans.FirewallConfigurationYaml;
+import it.polito.verigraph.tosca.yaml.beans.MailClientConfigurationYaml;
+import it.polito.verigraph.tosca.yaml.beans.MailServerConfigurationYaml;
+import it.polito.verigraph.tosca.yaml.beans.NatConfigurationYaml;
+import it.polito.verigraph.tosca.yaml.beans.VpnAccessConfigurationYaml;
+import it.polito.verigraph.tosca.yaml.beans.VpnExitConfigurationYaml;
+import it.polito.verigraph.tosca.yaml.beans.WebClientConfigurationYaml;
+import it.polito.verigraph.tosca.yaml.beans.WebServerConfigurationYaml;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+public class YamlConfigurationDeserializer extends JsonDeserializer<ConfigurationYaml> {
+
+ @Override
+ public ConfigurationYaml deserialize(JsonParser jp, DeserializationContext ctxt)
+ throws IOException, JsonProcessingException {
+ ObjectCodec oc = jp.getCodec();
+ JsonNode node = oc.readTree(jp);
+ ConfigurationYaml deserialized;
+ boolean emptyConfig = false;
+
+ try {
+ //Get the content from the array wrapping the JSON configuration
+ final Iterator<JsonNode> elements = node.elements();
+
+ if(!elements.hasNext()) {
+ //System.out.println("The provided configuration is empty.");
+ emptyConfig = true;
+ }
+
+ switch ((String)ctxt.findInjectableValue("type", null, null)) {
+
+ case "antispam":
+ if(emptyConfig) {
+ deserialized = new AntispamConfigurationYaml();
+ break;
+ }
+ AntispamConfigurationYaml antispam = new AntispamConfigurationYaml();
+ antispam.setSources(new ArrayList<String>());
+ while (elements.hasNext()) {
+ antispam.getSources().add(elements.next().asText());
+ }
+ deserialized = antispam;
+ break;
+
+ case "cache":
+ if(emptyConfig) {
+ deserialized = new CacheConfigurationYaml();
+ break;
+ }
+ CacheConfigurationYaml cache = new CacheConfigurationYaml();
+ cache.setResources(new ArrayList<String>());
+ while(elements.hasNext()) {
+ cache.getResources().add(elements.next().asText());
+ }
+ deserialized = cache;
+ break;
+
+ case "dpi":
+ if(emptyConfig) {
+ deserialized = new DpiConfigurationYaml();
+ break;
+ }
+ DpiConfigurationYaml dpi = new DpiConfigurationYaml();
+ dpi.setNotAllowedList(new ArrayList<String>());
+ while(elements.hasNext()) {
+ dpi.getNotAllowedList().add(elements.next().asText());
+ }
+ deserialized = dpi;
+ break;
+
+ case "endhost":
+ if(emptyConfig) {
+ deserialized = new EndhostConfigurationYaml();
+ break;
+ }
+ EndhostConfigurationYaml endhost = new EndhostConfigurationYaml();
+ JsonNode thisnode = elements.next();
+ if(thisnode.has("body"))
+ endhost.setBody(thisnode.findValue("body").asText());
+ if(thisnode.has("sequence"))
+ endhost.setSequence(Integer.valueOf(thisnode.findValue("sequence").asText()));
+ if(thisnode.has("protocol"))
+ endhost.setProtocol(thisnode.findValue("protocol").asText());
+ if(thisnode.has("email_from"))
+ endhost.setEmail_from(thisnode.findValue("email_from").asText());
+ if(thisnode.has("options"))
+ endhost.setOptions(thisnode.findValue("options").asText());
+ if(thisnode.has("url"))
+ endhost.setUrl(thisnode.findValue("url").asText());
+ if(thisnode.has("destination"))
+ endhost.setDestination(thisnode.findValue("destination").asText());
+
+ deserialized = endhost;
+ break;
+
+ case "endpoint":
+ if(emptyConfig) {
+ deserialized = new EndpointConfigurationYaml();
+ break;
+ }
+ EndpointConfigurationYaml endpoint = new EndpointConfigurationYaml();
+ deserialized = endpoint;
+ break;
+
+ case "fieldmodifier":
+ if(emptyConfig) {
+ deserialized = new FieldModifierConfigurationYaml();
+ break;
+ }
+ FieldModifierConfigurationYaml fieldmodifier = new FieldModifierConfigurationYaml();
+ deserialized = fieldmodifier;
+ break;
+
+ case "firewall":
+ if(emptyConfig) {
+ deserialized = new FirewallConfigurationYaml();
+ break;
+ }
+ FirewallConfigurationYaml firewall = new FirewallConfigurationYaml();
+ firewall.setElements(new HashMap<String,String>());
+ JsonNode current = elements.next();
+ Iterator<Map.Entry<String, JsonNode>> iter = current.fields();
+
+ while (iter.hasNext()) {
+ Map.Entry<String, JsonNode> entry = iter.next();
+ firewall.getElements().put(entry.getKey(), entry.getValue().asText());
+ }
+
+ deserialized = firewall;
+ break;
+
+ case "mailclient":
+ if(emptyConfig) {
+ deserialized = new MailClientConfigurationYaml();
+ break;
+ }
+ MailClientConfigurationYaml mailclient = new MailClientConfigurationYaml();
+ mailclient.setMailserver(elements.next().findValue("mailserver").asText());
+ deserialized = mailclient;
+ break;
+
+ case "mailserver":
+ if(emptyConfig) {
+ deserialized = new MailServerConfigurationYaml();
+ break;
+ }
+ MailServerConfigurationYaml mailserver = new MailServerConfigurationYaml();
+ deserialized = mailserver;
+ break;
+
+ case "nat":
+ if(emptyConfig) {
+ deserialized = new NatConfigurationYaml();
+ break;
+ }
+ NatConfigurationYaml nat = new NatConfigurationYaml();
+ nat.setSources(new ArrayList<String>());
+ while(elements.hasNext()) {
+ nat.getSources().add(elements.next().asText());
+ }
+ deserialized = nat;
+ break;
+
+ case "vpnaccess":
+ if(emptyConfig) {
+ deserialized = new VpnAccessConfigurationYaml();
+ break;
+ }
+ VpnAccessConfigurationYaml vpnaccess = new VpnAccessConfigurationYaml();
+ vpnaccess.setVpnexit(elements.next().findValue("vpnexit").asText());
+ deserialized = vpnaccess;
+ break;
+
+ case "vpnexit":
+ if(emptyConfig) {
+ deserialized = new VpnExitConfigurationYaml();
+ break;
+ }
+ VpnExitConfigurationYaml vpnexit = new VpnExitConfigurationYaml();
+ vpnexit.setVpnaccess(elements.next().findValue("vpnaccess").asText());
+ deserialized = vpnexit;
+ break;
+
+ case "webclient":
+ if(emptyConfig) {
+ deserialized = new WebClientConfigurationYaml();
+ break;
+ }
+ WebClientConfigurationYaml webclient = new WebClientConfigurationYaml();
+ webclient.setNameWebServer(elements.next().findValue("webserver").asText());
+ deserialized = webclient;
+ break;
+
+ case "webserver":
+ if(emptyConfig) {
+ deserialized = new WebServerConfigurationYaml();
+ break;
+ }
+ WebServerConfigurationYaml webserver = new WebServerConfigurationYaml();
+ deserialized = webserver;
+ break;
+
+ default:
+ deserialized = new FieldModifierConfigurationYaml();
+ break;
+ }
+
+
+ } catch (Exception e) {
+ // TODO Auto-generated catch block
+ //System.err.println("Error converting the Json to YamlConfiguration");
+ e.printStackTrace();
+ return new FieldModifierConfigurationYaml();
+ }
+
+ return deserialized;
+
+ }
+
+}
\ No newline at end of file diff --git a/verigraph/src/it/polito/verigraph/tosca/serializer/XmlConfigSerializer.java b/verigraph/src/it/polito/verigraph/tosca/serializer/XmlConfigSerializer.java new file mode 100644 index 0000000..b650420 --- /dev/null +++ b/verigraph/src/it/polito/verigraph/tosca/serializer/XmlConfigSerializer.java @@ -0,0 +1,163 @@ +/*******************************************************************************
+ * Copyright (c) 2018 Politecnico di Torino and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Apache License, Version 2.0
+ * which accompanies this distribution, and is available at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+package it.polito.verigraph.tosca.serializer;
+
+import java.io.IOException;
+
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.SerializerProvider;
+import com.fasterxml.jackson.databind.ser.std.StdSerializer;
+
+import it.polito.tosca.jaxb.Configuration;
+
+//Custom serializer for XmlToscaConfigurationObject conversion to JSON
+public class XmlConfigSerializer extends StdSerializer<Configuration> {
+
+ //Automatically generated VersionUID
+ private static final long serialVersionUID = 9102508941195129607L;
+
+ public XmlConfigSerializer() {
+ this(null);
+ }
+
+ public XmlConfigSerializer(Class<Configuration> t) {
+ super(t);
+ }
+
+ @Override
+ public void serialize(
+ Configuration value, JsonGenerator jgen, SerializerProvider provider)
+ throws IOException, JsonProcessingException {
+
+ if (value.getAntispamConfiguration() != null) {
+ jgen.writeStartArray();
+ for(String source : value.getAntispamConfiguration().getSource()) {
+ jgen.writeString(source);
+ }
+ jgen.writeEndArray();
+
+ } else if (value.getCacheConfiguration() != null) {
+ jgen.writeStartArray();
+ for(String resource : value.getCacheConfiguration().getResource()) {
+ jgen.writeString(resource);
+ }
+ jgen.writeEndArray();
+
+ } else if (value.getDpiConfiguration() != null) {
+ jgen.writeStartArray();
+ for(String notAllowed : value.getDpiConfiguration().getNotAllowed()) {
+ jgen.writeString(notAllowed);
+ }
+ jgen.writeEndArray();
+
+ } else if (value.getEndhostConfiguration() != null) {
+ jgen.writeStartArray();
+ jgen.writeStartObject();
+
+ Configuration.EndhostConfiguration endhost = value.getEndhostConfiguration();
+ if (endhost.getBody() != null) jgen.writeObjectField("body", endhost.getBody());
+ if (endhost.getSequence() != null) jgen.writeObjectField("sequence", endhost.getSequence());
+ if (endhost.getProtocol() != null) jgen.writeObjectField("protocol", endhost.getProtocol());
+ if (endhost.getEmailFrom() != null) jgen.writeObjectField("email_from", endhost.getEmailFrom());
+ if (endhost.getUrl() != null) jgen.writeObjectField("url", endhost.getUrl());
+ if (endhost.getOptions() != null) jgen.writeObjectField("options", endhost.getOptions());
+ if (endhost.getDestination() != null) jgen.writeObjectField("destination", endhost.getDestination());
+
+ jgen.writeEndObject();
+ jgen.writeEndArray();
+
+ } else if (value.getEndpointConfiguration() != null) {
+ jgen.writeStartArray();
+ jgen.writeEndArray();
+
+ } else if (value.getFieldmodifierConfiguration() != null) {
+ jgen.writeStartArray();
+ jgen.writeEndArray();
+
+ } else if (value.getFirewallConfiguration() != null) {
+ jgen.writeStartArray();
+
+ for(Configuration.FirewallConfiguration.Elements elem : value.getFirewallConfiguration().getElements()) {
+ if ((elem.getSource() != null) && (elem.getDestination() != null)) {
+ jgen.writeStartObject();
+ jgen.writeObjectField(elem.getSource(), elem.getDestination());
+ jgen.writeEndObject();
+ }
+ }
+
+ jgen.writeEndArray();
+
+ } else if (value.getMailclientConfiguration() != null) {
+ jgen.writeStartArray();
+
+ if (value.getMailclientConfiguration().getMailserver() != null) {
+ jgen.writeStartObject();
+ jgen.writeObjectField("mailserver", value.getMailclientConfiguration().getMailserver());
+ jgen.writeEndObject();
+ }
+
+ jgen.writeEndArray();
+
+ } else if (value.getMailserverConfiguration() != null) {
+ jgen.writeStartArray();
+ jgen.writeEndArray();
+
+ } else if (value.getNatConfiguration() != null) {
+ jgen.writeStartArray();
+ for(String source : value.getNatConfiguration().getSource()) {
+ jgen.writeString(source);
+ }
+ jgen.writeEndArray();
+
+ } else if (value.getVpnaccessConfiguration() != null) {
+ jgen.writeStartArray();
+
+ if (value.getVpnaccessConfiguration().getVpnexit()!= null) {
+ jgen.writeStartObject();
+ jgen.writeObjectField("vpnexit", value.getVpnaccessConfiguration().getVpnexit());
+ jgen.writeEndObject();
+ }
+
+ jgen.writeEndArray();
+
+ } else if (value.getVpnexitConfiguration() != null) {
+ jgen.writeStartArray();
+
+ if (value.getVpnexitConfiguration().getVpnaccess()!= null) {
+ jgen.writeStartObject();
+ jgen.writeObjectField("vpnaccess", value.getVpnexitConfiguration().getVpnaccess());
+ jgen.writeEndObject();
+ }
+
+ jgen.writeEndArray();
+
+ } else if (value.getWebclientConfiguration() != null) {
+ jgen.writeStartArray();
+
+ if (value.getWebclientConfiguration().getNameWebServer() != null) {
+ jgen.writeStartObject();
+ jgen.writeObjectField("webserver", value.getWebclientConfiguration().getNameWebServer());
+ jgen.writeEndObject();
+ }
+
+ jgen.writeEndArray();
+
+ } else if (value.getWebserverConfiguration() != null) {
+ jgen.writeStartArray();
+ jgen.writeEndArray();
+
+ } else {
+ //Case of empty Configuration
+ jgen.writeStartArray();
+ jgen.writeEndArray();
+ }
+
+ }
+}
diff --git a/verigraph/src/it/polito/verigraph/tosca/serializer/YamlConfigSerializer.java b/verigraph/src/it/polito/verigraph/tosca/serializer/YamlConfigSerializer.java new file mode 100644 index 0000000..05a1629 --- /dev/null +++ b/verigraph/src/it/polito/verigraph/tosca/serializer/YamlConfigSerializer.java @@ -0,0 +1,186 @@ +/*******************************************************************************
+ * Copyright (c) 2018 Politecnico di Torino and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Apache License, Version 2.0
+ * which accompanies this distribution, and is available at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+package it.polito.verigraph.tosca.serializer;
+
+import java.io.IOException;
+import java.util.Map;
+
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.SerializerProvider;
+import com.fasterxml.jackson.databind.ser.std.StdSerializer;
+
+import it.polito.verigraph.tosca.yaml.beans.AntispamConfigurationYaml;
+import it.polito.verigraph.tosca.yaml.beans.CacheConfigurationYaml;
+import it.polito.verigraph.tosca.yaml.beans.ConfigurationYaml;
+import it.polito.verigraph.tosca.yaml.beans.DpiConfigurationYaml;
+import it.polito.verigraph.tosca.yaml.beans.EndhostConfigurationYaml;
+import it.polito.verigraph.tosca.yaml.beans.EndpointConfigurationYaml;
+import it.polito.verigraph.tosca.yaml.beans.FieldModifierConfigurationYaml;
+import it.polito.verigraph.tosca.yaml.beans.FirewallConfigurationYaml;
+import it.polito.verigraph.tosca.yaml.beans.MailClientConfigurationYaml;
+import it.polito.verigraph.tosca.yaml.beans.MailServerConfigurationYaml;
+import it.polito.verigraph.tosca.yaml.beans.NatConfigurationYaml;
+import it.polito.verigraph.tosca.yaml.beans.VpnAccessConfigurationYaml;
+import it.polito.verigraph.tosca.yaml.beans.VpnExitConfigurationYaml;
+import it.polito.verigraph.tosca.yaml.beans.WebClientConfigurationYaml;
+import it.polito.verigraph.tosca.yaml.beans.WebServerConfigurationYaml;
+
+//Custom serializer for YamlToscaConfigurationObject conversion to JSON
+public class YamlConfigSerializer extends StdSerializer<ConfigurationYaml> {
+
+ //Automatically generated VersionUID
+ private static final long serialVersionUID = 9102508941195129607L;
+
+ public YamlConfigSerializer() {
+ this(null);
+ }
+
+ public YamlConfigSerializer(Class<ConfigurationYaml> t) {
+ super(t);
+ }
+
+ @Override
+ public void serialize(
+ ConfigurationYaml value, JsonGenerator jgen, SerializerProvider provider)
+ throws IOException, JsonProcessingException {
+
+ if(value instanceof AntispamConfigurationYaml) {
+ jgen.writeStartArray();
+ for(String source : ((AntispamConfigurationYaml) value).getSources()) {
+ jgen.writeString(source);
+ }
+ jgen.writeEndArray();
+
+ }else if(value instanceof CacheConfigurationYaml) {
+ jgen.writeStartArray();
+ for(String resource : ((CacheConfigurationYaml) value).getResources()) {
+ jgen.writeString(resource);
+ }
+ jgen.writeEndArray();
+
+ }else if(value instanceof DpiConfigurationYaml) {
+ jgen.writeStartArray();
+ for(String notAllowed : ((DpiConfigurationYaml) value).getNotAllowedList()) {
+ jgen.writeString(notAllowed);
+ }
+ jgen.writeEndArray();
+
+ }else if(value instanceof EndhostConfigurationYaml) {
+ jgen.writeStartArray();
+ jgen.writeStartObject();
+
+ EndhostConfigurationYaml endhost = (EndhostConfigurationYaml) value;
+
+ if(endhost.getBody() != null)
+ jgen.writeObjectField("body", endhost.getBody());
+ if(endhost.getSequence() != 0)
+ jgen.writeObjectField("sequence", endhost.getSequence());
+ if(endhost.getProtocol() != null)
+ jgen.writeObjectField("protocol", endhost.getProtocol());
+ if(endhost.getEmail_from() != null)
+ jgen.writeObjectField("email_from", endhost.getEmail_from());
+ if(endhost.getUrl() != null)
+ jgen.writeObjectField("url", endhost.getUrl());
+ if(endhost.getOptions() != null)
+ jgen.writeObjectField("options", endhost.getOptions());
+ if(endhost.getDestination() != null)
+ jgen.writeObjectField("destination", endhost.getDestination());
+
+ jgen.writeEndObject();
+ jgen.writeEndArray();
+
+ }else if(value instanceof EndpointConfigurationYaml) {
+ jgen.writeStartArray();
+ jgen.writeEndArray();
+
+ }else if(value instanceof FieldModifierConfigurationYaml) {
+ jgen.writeStartArray();
+ jgen.writeEndArray();
+
+ }else if(value instanceof FirewallConfigurationYaml) {
+ jgen.writeStartArray();
+ FirewallConfigurationYaml fw = (FirewallConfigurationYaml) value;
+
+ for(Map.Entry<String, String> entry : fw.getElements().entrySet()) {
+ if(entry.getKey()!= null && entry.getValue() != null) {
+ jgen.writeStartObject();
+ jgen.writeObjectField(entry.getKey(), entry.getValue());
+ jgen.writeEndObject();
+ }
+ }
+ jgen.writeEndArray();
+
+ }else if(value instanceof MailClientConfigurationYaml) {
+ jgen.writeStartArray();
+
+ if(((MailClientConfigurationYaml) value).getMailserver() != null) {
+ jgen.writeStartObject();
+ jgen.writeObjectField("mailserver", ((MailClientConfigurationYaml) value).getMailserver());
+ jgen.writeEndObject();
+ }
+ jgen.writeEndArray();
+
+ }else if(value instanceof MailServerConfigurationYaml) {
+ jgen.writeStartArray();
+ jgen.writeEndArray();
+
+ }else if(value instanceof NatConfigurationYaml) {
+ jgen.writeStartArray();
+
+ for(String source : ((NatConfigurationYaml) value).getSources()) {
+ jgen.writeString(source);
+ }
+
+ jgen.writeEndArray();
+
+ }else if(value instanceof VpnAccessConfigurationYaml) {
+ jgen.writeStartArray();
+
+ if(((VpnAccessConfigurationYaml) value).getVpnexit()!= null) {
+ jgen.writeStartObject();
+ jgen.writeObjectField("vpnexit", ((VpnAccessConfigurationYaml) value).getVpnexit());
+ jgen.writeEndObject();
+ }
+
+ jgen.writeEndArray();
+
+ }else if(value instanceof VpnExitConfigurationYaml) {
+ jgen.writeStartArray();
+
+ if(((VpnExitConfigurationYaml) value).getVpnaccess()!= null) {
+ jgen.writeStartObject();
+ jgen.writeObjectField("vpnaccess", ((VpnExitConfigurationYaml) value).getVpnaccess());
+ jgen.writeEndObject();
+ }
+
+ jgen.writeEndArray();
+
+ }else if(value instanceof WebClientConfigurationYaml) {
+ jgen.writeStartArray();
+
+ if(((WebClientConfigurationYaml) value).getNameWebServer() != null) {
+ jgen.writeStartObject();
+ jgen.writeObjectField("webserver", ((WebClientConfigurationYaml) value).getNameWebServer());
+ jgen.writeEndObject();
+ }
+
+ jgen.writeEndArray();
+
+ }else if(value instanceof WebServerConfigurationYaml) {
+ jgen.writeStartArray();
+ jgen.writeEndArray();
+
+ }else {
+ jgen.writeStartArray();
+ jgen.writeEndArray();
+ }
+
+ }
+}
diff --git a/verigraph/src/it/polito/verigraph/tosca/yaml/beans/AntispamConfigurationYaml.java b/verigraph/src/it/polito/verigraph/tosca/yaml/beans/AntispamConfigurationYaml.java new file mode 100644 index 0000000..b0a082d --- /dev/null +++ b/verigraph/src/it/polito/verigraph/tosca/yaml/beans/AntispamConfigurationYaml.java @@ -0,0 +1,24 @@ +/*******************************************************************************
+ * Copyright (c) 2018 Politecnico di Torino and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Apache License, Version 2.0
+ * which accompanies this distribution, and is available at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+package it.polito.verigraph.tosca.yaml.beans;
+
+import java.util.List;
+
+public class AntispamConfigurationYaml implements ConfigurationYaml {
+ private List<String> sources;
+
+ public List<String> getSources() {
+ return sources;
+ }
+
+ public void setSources(List<String> sources) {
+ this.sources = sources;
+ }
+
+}
diff --git a/verigraph/src/it/polito/verigraph/tosca/yaml/beans/AntispamNode.java b/verigraph/src/it/polito/verigraph/tosca/yaml/beans/AntispamNode.java new file mode 100644 index 0000000..9d02e87 --- /dev/null +++ b/verigraph/src/it/polito/verigraph/tosca/yaml/beans/AntispamNode.java @@ -0,0 +1,24 @@ +/*******************************************************************************
+ * Copyright (c) 2018 Politecnico di Torino and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Apache License, Version 2.0
+ * which accompanies this distribution, and is available at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+package it.polito.verigraph.tosca.yaml.beans;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class AntispamNode extends NodeTemplateYaml {
+ private AntispamConfigurationYaml properties;
+
+ public AntispamConfigurationYaml getProperties() {
+ return properties;
+ }
+
+ public void setProperties(AntispamConfigurationYaml properties) {
+ this.properties = properties;
+ }
+}
diff --git a/verigraph/src/it/polito/verigraph/tosca/yaml/beans/CacheConfigurationYaml.java b/verigraph/src/it/polito/verigraph/tosca/yaml/beans/CacheConfigurationYaml.java new file mode 100644 index 0000000..5cf03cd --- /dev/null +++ b/verigraph/src/it/polito/verigraph/tosca/yaml/beans/CacheConfigurationYaml.java @@ -0,0 +1,26 @@ +/*******************************************************************************
+ * Copyright (c) 2018 Politecnico di Torino and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Apache License, Version 2.0
+ * which accompanies this distribution, and is available at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+package it.polito.verigraph.tosca.yaml.beans;
+
+import java.util.List;
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class CacheConfigurationYaml implements ConfigurationYaml {
+ private List<String> resources;
+
+ public List<String> getResources() {
+ return resources;
+ }
+
+ public void setResources(List<String> resources) {
+ this.resources = resources;
+ }
+
+}
diff --git a/verigraph/src/it/polito/verigraph/tosca/yaml/beans/CacheNode.java b/verigraph/src/it/polito/verigraph/tosca/yaml/beans/CacheNode.java new file mode 100644 index 0000000..99adb2e --- /dev/null +++ b/verigraph/src/it/polito/verigraph/tosca/yaml/beans/CacheNode.java @@ -0,0 +1,22 @@ +/*******************************************************************************
+ * Copyright (c) 2018 Politecnico di Torino and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Apache License, Version 2.0
+ * which accompanies this distribution, and is available at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+package it.polito.verigraph.tosca.yaml.beans;
+
+public class CacheNode extends NodeTemplateYaml {
+ private CacheConfigurationYaml properties;
+
+ public CacheConfigurationYaml getProperties() {
+ return properties;
+ }
+
+ public void setProperties(CacheConfigurationYaml properties) {
+ this.properties = properties;
+ }
+
+}
diff --git a/verigraph/src/it/polito/verigraph/tosca/yaml/beans/ConfigurationYaml.java b/verigraph/src/it/polito/verigraph/tosca/yaml/beans/ConfigurationYaml.java new file mode 100644 index 0000000..b0e4000 --- /dev/null +++ b/verigraph/src/it/polito/verigraph/tosca/yaml/beans/ConfigurationYaml.java @@ -0,0 +1,16 @@ +/*******************************************************************************
+ * Copyright (c) 2018 Politecnico di Torino and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Apache License, Version 2.0
+ * which accompanies this distribution, and is available at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+package it.polito.verigraph.tosca.yaml.beans;
+
+
+//Empty interface implemented by all the Yaml configuration beans allowing
+//an easier and type indipendet use of the objects
+public interface ConfigurationYaml {
+
+}
diff --git a/verigraph/src/it/polito/verigraph/tosca/yaml/beans/DpiConfigurationYaml.java b/verigraph/src/it/polito/verigraph/tosca/yaml/beans/DpiConfigurationYaml.java new file mode 100644 index 0000000..3074780 --- /dev/null +++ b/verigraph/src/it/polito/verigraph/tosca/yaml/beans/DpiConfigurationYaml.java @@ -0,0 +1,26 @@ +/*******************************************************************************
+ * Copyright (c) 2018 Politecnico di Torino and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Apache License, Version 2.0
+ * which accompanies this distribution, and is available at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+package it.polito.verigraph.tosca.yaml.beans;
+
+import java.util.List;
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class DpiConfigurationYaml implements ConfigurationYaml{
+ private List<String> notAllowedList;
+
+ public List<String> getNotAllowedList() {
+ return notAllowedList;
+ }
+
+ public void setNotAllowedList(List<String> notAllowedList) {
+ this.notAllowedList = notAllowedList;
+ }
+
+}
diff --git a/verigraph/src/it/polito/verigraph/tosca/yaml/beans/DpiNode.java b/verigraph/src/it/polito/verigraph/tosca/yaml/beans/DpiNode.java new file mode 100644 index 0000000..d200cc2 --- /dev/null +++ b/verigraph/src/it/polito/verigraph/tosca/yaml/beans/DpiNode.java @@ -0,0 +1,22 @@ +/*******************************************************************************
+ * Copyright (c) 2018 Politecnico di Torino and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Apache License, Version 2.0
+ * which accompanies this distribution, and is available at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+package it.polito.verigraph.tosca.yaml.beans;
+
+public class DpiNode extends NodeTemplateYaml {
+ private DpiConfigurationYaml properties;
+
+ public DpiConfigurationYaml getProperties() {
+ return properties;
+ }
+
+ public void setProperties(DpiConfigurationYaml properties) {
+ this.properties = properties;
+ }
+
+}
diff --git a/verigraph/src/it/polito/verigraph/tosca/yaml/beans/EndhostConfigurationYaml.java b/verigraph/src/it/polito/verigraph/tosca/yaml/beans/EndhostConfigurationYaml.java new file mode 100644 index 0000000..e1cfbd8 --- /dev/null +++ b/verigraph/src/it/polito/verigraph/tosca/yaml/beans/EndhostConfigurationYaml.java @@ -0,0 +1,67 @@ +/*******************************************************************************
+ * Copyright (c) 2018 Politecnico di Torino and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Apache License, Version 2.0
+ * which accompanies this distribution, and is available at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+package it.polito.verigraph.tosca.yaml.beans;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class EndhostConfigurationYaml implements ConfigurationYaml{
+ private String body;
+ private int sequence;
+ private String protocol;
+ private String email_from;
+ private String url;
+ private String options;
+ private String destination;
+
+ public String getBody() {
+ return body;
+ }
+ public void setBody(String body) {
+ this.body = body;
+ }
+ public int getSequence() {
+ return sequence;
+ }
+ public void setSequence(int sequence) {
+ this.sequence = sequence;
+ }
+ public String getProtocol() {
+ return protocol;
+ }
+ public void setProtocol(String protocol) {
+ this.protocol = protocol;
+ }
+ public String getEmail_from() {
+ return email_from;
+ }
+ public void setEmail_from(String email_from) {
+ this.email_from = email_from;
+ }
+ public String getUrl() {
+ return url;
+ }
+ public void setUrl(String url) {
+ this.url = url;
+ }
+ public String getOptions() {
+ return options;
+ }
+ public void setOptions(String options) {
+ this.options = options;
+ }
+ public String getDestination() {
+ return destination;
+ }
+ public void setDestination(String destination) {
+ this.destination = destination;
+ }
+
+
+}
diff --git a/verigraph/src/it/polito/verigraph/tosca/yaml/beans/EndhostNode.java b/verigraph/src/it/polito/verigraph/tosca/yaml/beans/EndhostNode.java new file mode 100644 index 0000000..c47b14e --- /dev/null +++ b/verigraph/src/it/polito/verigraph/tosca/yaml/beans/EndhostNode.java @@ -0,0 +1,22 @@ +/*******************************************************************************
+ * Copyright (c) 2018 Politecnico di Torino and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Apache License, Version 2.0
+ * which accompanies this distribution, and is available at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+package it.polito.verigraph.tosca.yaml.beans;
+
+public class EndhostNode extends NodeTemplateYaml{
+ private EndhostConfigurationYaml properties;
+
+ public EndhostConfigurationYaml getProperties() {
+ return properties;
+ }
+
+ public void setProperties(EndhostConfigurationYaml properties) {
+ this.properties = properties;
+ }
+
+}
diff --git a/verigraph/src/it/polito/verigraph/tosca/yaml/beans/EndpointConfigurationYaml.java b/verigraph/src/it/polito/verigraph/tosca/yaml/beans/EndpointConfigurationYaml.java new file mode 100644 index 0000000..76cbec6 --- /dev/null +++ b/verigraph/src/it/polito/verigraph/tosca/yaml/beans/EndpointConfigurationYaml.java @@ -0,0 +1,26 @@ +/*******************************************************************************
+ * Copyright (c) 2018 Politecnico di Torino and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Apache License, Version 2.0
+ * which accompanies this distribution, and is available at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+package it.polito.verigraph.tosca.yaml.beans;
+
+import java.util.List;
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class EndpointConfigurationYaml implements ConfigurationYaml{
+ private List<String> names;
+
+ public List<String> getNames() {
+ return names;
+ }
+
+ public void setNames(List<String> names) {
+ this.names = names;
+ }
+
+}
diff --git a/verigraph/src/it/polito/verigraph/tosca/yaml/beans/EndpointNode.java b/verigraph/src/it/polito/verigraph/tosca/yaml/beans/EndpointNode.java new file mode 100644 index 0000000..06b50cd --- /dev/null +++ b/verigraph/src/it/polito/verigraph/tosca/yaml/beans/EndpointNode.java @@ -0,0 +1,22 @@ +/*******************************************************************************
+ * Copyright (c) 2018 Politecnico di Torino and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Apache License, Version 2.0
+ * which accompanies this distribution, and is available at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+package it.polito.verigraph.tosca.yaml.beans;
+
+public class EndpointNode extends NodeTemplateYaml {
+ private EndpointConfigurationYaml properties;
+
+ public EndpointConfigurationYaml getProperties() {
+ return properties;
+ }
+
+ public void setProperties(EndpointConfigurationYaml properties) {
+ this.properties = properties;
+ }
+
+}
diff --git a/verigraph/src/it/polito/verigraph/tosca/yaml/beans/FieldModifierConfigurationYaml.java b/verigraph/src/it/polito/verigraph/tosca/yaml/beans/FieldModifierConfigurationYaml.java new file mode 100644 index 0000000..64ff4c7 --- /dev/null +++ b/verigraph/src/it/polito/verigraph/tosca/yaml/beans/FieldModifierConfigurationYaml.java @@ -0,0 +1,26 @@ +/*******************************************************************************
+ * Copyright (c) 2018 Politecnico di Torino and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Apache License, Version 2.0
+ * which accompanies this distribution, and is available at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+package it.polito.verigraph.tosca.yaml.beans;
+
+import java.util.List;
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class FieldModifierConfigurationYaml implements ConfigurationYaml{
+ private List<String> names;
+
+ public List<String> getNames() {
+ return names;
+ }
+
+ public void setNames(List<String> names) {
+ this.names = names;
+ }
+
+}
diff --git a/verigraph/src/it/polito/verigraph/tosca/yaml/beans/FieldModifierNode.java b/verigraph/src/it/polito/verigraph/tosca/yaml/beans/FieldModifierNode.java new file mode 100644 index 0000000..f805337 --- /dev/null +++ b/verigraph/src/it/polito/verigraph/tosca/yaml/beans/FieldModifierNode.java @@ -0,0 +1,21 @@ +/*******************************************************************************
+ * Copyright (c) 2018 Politecnico di Torino and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Apache License, Version 2.0
+ * which accompanies this distribution, and is available at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+package it.polito.verigraph.tosca.yaml.beans;
+
+public class FieldModifierNode extends NodeTemplateYaml {
+ private FieldModifierConfigurationYaml properties;
+
+ public FieldModifierConfigurationYaml getProperties() {
+ return properties;
+ }
+
+ public void setProperties(FieldModifierConfigurationYaml properties) {
+ this.properties = properties;
+ }
+}
diff --git a/verigraph/src/it/polito/verigraph/tosca/yaml/beans/FirewallConfigurationYaml.java b/verigraph/src/it/polito/verigraph/tosca/yaml/beans/FirewallConfigurationYaml.java new file mode 100644 index 0000000..85634d4 --- /dev/null +++ b/verigraph/src/it/polito/verigraph/tosca/yaml/beans/FirewallConfigurationYaml.java @@ -0,0 +1,24 @@ +/*******************************************************************************
+ * Copyright (c) 2018 Politecnico di Torino and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Apache License, Version 2.0
+ * which accompanies this distribution, and is available at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+package it.polito.verigraph.tosca.yaml.beans;
+
+import java.util.Map;
+
+public class FirewallConfigurationYaml implements ConfigurationYaml{
+ private Map<String, String> elements;
+
+ public Map<String, String> getElements() {
+ return elements;
+ }
+
+ public void setElements(Map<String, String> elements) {
+ this.elements = elements;
+ }
+
+}
diff --git a/verigraph/src/it/polito/verigraph/tosca/yaml/beans/FirewallNode.java b/verigraph/src/it/polito/verigraph/tosca/yaml/beans/FirewallNode.java new file mode 100644 index 0000000..d8952ae --- /dev/null +++ b/verigraph/src/it/polito/verigraph/tosca/yaml/beans/FirewallNode.java @@ -0,0 +1,22 @@ +/*******************************************************************************
+ * Copyright (c) 2018 Politecnico di Torino and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Apache License, Version 2.0
+ * which accompanies this distribution, and is available at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+package it.polito.verigraph.tosca.yaml.beans;
+
+public class FirewallNode extends NodeTemplateYaml {
+ private FirewallConfigurationYaml properties;
+
+ public FirewallConfigurationYaml getProperties() {
+ return properties;
+ }
+
+ public void setProperties(FirewallConfigurationYaml properties) {
+ this.properties = properties;
+ }
+
+}
diff --git a/verigraph/src/it/polito/verigraph/tosca/yaml/beans/MailClientConfigurationYaml.java b/verigraph/src/it/polito/verigraph/tosca/yaml/beans/MailClientConfigurationYaml.java new file mode 100644 index 0000000..2120c4d --- /dev/null +++ b/verigraph/src/it/polito/verigraph/tosca/yaml/beans/MailClientConfigurationYaml.java @@ -0,0 +1,24 @@ +/*******************************************************************************
+ * Copyright (c) 2018 Politecnico di Torino and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Apache License, Version 2.0
+ * which accompanies this distribution, and is available at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+package it.polito.verigraph.tosca.yaml.beans;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class MailClientConfigurationYaml implements ConfigurationYaml {
+ private String mailserver;
+
+ public String getMailserver() {
+ return mailserver;
+ }
+
+ public void setMailserver(String mailserver) {
+ this.mailserver = mailserver;
+ }
+}
diff --git a/verigraph/src/it/polito/verigraph/tosca/yaml/beans/MailClientNode.java b/verigraph/src/it/polito/verigraph/tosca/yaml/beans/MailClientNode.java new file mode 100644 index 0000000..fa75154 --- /dev/null +++ b/verigraph/src/it/polito/verigraph/tosca/yaml/beans/MailClientNode.java @@ -0,0 +1,21 @@ +/*******************************************************************************
+ * Copyright (c) 2018 Politecnico di Torino and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Apache License, Version 2.0
+ * which accompanies this distribution, and is available at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+package it.polito.verigraph.tosca.yaml.beans;
+
+public class MailClientNode extends NodeTemplateYaml {
+ private MailClientConfigurationYaml properties;
+
+ public MailClientConfigurationYaml getProperties() {
+ return properties;
+ }
+
+ public void setProperties(MailClientConfigurationYaml properties) {
+ this.properties = properties;
+ }
+}
diff --git a/verigraph/src/it/polito/verigraph/tosca/yaml/beans/MailServerConfigurationYaml.java b/verigraph/src/it/polito/verigraph/tosca/yaml/beans/MailServerConfigurationYaml.java new file mode 100644 index 0000000..3672727 --- /dev/null +++ b/verigraph/src/it/polito/verigraph/tosca/yaml/beans/MailServerConfigurationYaml.java @@ -0,0 +1,26 @@ +/*******************************************************************************
+ * Copyright (c) 2018 Politecnico di Torino and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Apache License, Version 2.0
+ * which accompanies this distribution, and is available at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+package it.polito.verigraph.tosca.yaml.beans;
+
+import java.util.List;
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class MailServerConfigurationYaml implements ConfigurationYaml {
+ private List<String> names;
+
+ public List<String> getNames() {
+ return names;
+ }
+
+ public void setNames(List<String> names) {
+ this.names = names;
+ }
+
+}
diff --git a/verigraph/src/it/polito/verigraph/tosca/yaml/beans/MailServerNode.java b/verigraph/src/it/polito/verigraph/tosca/yaml/beans/MailServerNode.java new file mode 100644 index 0000000..6f7d493 --- /dev/null +++ b/verigraph/src/it/polito/verigraph/tosca/yaml/beans/MailServerNode.java @@ -0,0 +1,21 @@ +/*******************************************************************************
+ * Copyright (c) 2018 Politecnico di Torino and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Apache License, Version 2.0
+ * which accompanies this distribution, and is available at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+package it.polito.verigraph.tosca.yaml.beans;
+
+public class MailServerNode extends NodeTemplateYaml {
+ private MailServerConfigurationYaml properties;
+
+ public MailServerConfigurationYaml getProperties() {
+ return properties;
+ }
+
+ public void setProperties(MailServerConfigurationYaml properties) {
+ this.properties = properties;
+ }
+}
diff --git a/verigraph/src/it/polito/verigraph/tosca/yaml/beans/NatConfigurationYaml.java b/verigraph/src/it/polito/verigraph/tosca/yaml/beans/NatConfigurationYaml.java new file mode 100644 index 0000000..49d34c8 --- /dev/null +++ b/verigraph/src/it/polito/verigraph/tosca/yaml/beans/NatConfigurationYaml.java @@ -0,0 +1,27 @@ +/*******************************************************************************
+ * Copyright (c) 2018 Politecnico di Torino and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Apache License, Version 2.0
+ * which accompanies this distribution, and is available at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+package it.polito.verigraph.tosca.yaml.beans;
+
+import java.util.List;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class NatConfigurationYaml implements ConfigurationYaml {
+ private List<String> sources;
+
+ public List<String> getSources() {
+ return sources;
+ }
+
+ public void setSources(List<String> sources) {
+ this.sources = sources;
+ }
+
+}
diff --git a/verigraph/src/it/polito/verigraph/tosca/yaml/beans/NatNode.java b/verigraph/src/it/polito/verigraph/tosca/yaml/beans/NatNode.java new file mode 100644 index 0000000..cd30172 --- /dev/null +++ b/verigraph/src/it/polito/verigraph/tosca/yaml/beans/NatNode.java @@ -0,0 +1,21 @@ +/*******************************************************************************
+ * Copyright (c) 2018 Politecnico di Torino and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Apache License, Version 2.0
+ * which accompanies this distribution, and is available at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+package it.polito.verigraph.tosca.yaml.beans;
+
+public class NatNode extends NodeTemplateYaml {
+ private NatConfigurationYaml properties;
+
+ public NatConfigurationYaml getProperties() {
+ return properties;
+ }
+
+ public void setProperties(NatConfigurationYaml properties) {
+ this.properties = properties;
+ }
+}
diff --git a/verigraph/src/it/polito/verigraph/tosca/yaml/beans/NodeTemplateYaml.java b/verigraph/src/it/polito/verigraph/tosca/yaml/beans/NodeTemplateYaml.java new file mode 100644 index 0000000..9821f7c --- /dev/null +++ b/verigraph/src/it/polito/verigraph/tosca/yaml/beans/NodeTemplateYaml.java @@ -0,0 +1,55 @@ +/*******************************************************************************
+ * Copyright (c) 2018 Politecnico di Torino and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Apache License, Version 2.0
+ * which accompanies this distribution, and is available at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+package it.polito.verigraph.tosca.yaml.beans;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.*;
+
+//These annotations allow polimorphic deserialization of yaml text into beans by using the type field of each node
+//In case a specified type is unknown the default implementation will be FieldModifierNode
+@JsonIgnoreProperties(ignoreUnknown = true)
+@JsonTypeInfo(use=JsonTypeInfo.Id.NAME, include=JsonTypeInfo.As.PROPERTY, property="type", defaultImpl=FieldModifierNode.class, visible= true)
+@JsonSubTypes({
+ @JsonSubTypes.Type(value = AntispamNode.class, name="verigraph.nodeTypes.Antispam"),
+ @JsonSubTypes.Type(value = CacheNode.class, name="verigraph.nodeTypes.Cache"),
+ @JsonSubTypes.Type(value = DpiNode.class, name="verigraph.nodeTypes.Dpi"),
+ @JsonSubTypes.Type(value = EndhostNode.class, name="verigraph.nodeTypes.Endhost"),
+ @JsonSubTypes.Type(value = EndpointNode.class, name="verigraph.nodeTypes.Endpoint"),
+ @JsonSubTypes.Type(value = FieldModifierNode.class, name="verigraph.nodeTypes.FieldModifier"),
+ @JsonSubTypes.Type(value = FirewallNode.class, name="verigraph.nodeTypes.Firewall"),
+ @JsonSubTypes.Type(value = MailClientNode.class, name="verigraph.nodeTypes.MailClient"),
+ @JsonSubTypes.Type(value = MailServerNode.class, name="verigraph.nodeTypes.MailServer"),
+ @JsonSubTypes.Type(value = NatNode.class, name="verigraph.nodeTypes.Nat"),
+ @JsonSubTypes.Type(value = VpnAccessNode.class, name="verigraph.nodeTypes.VpnAccess"),
+ @JsonSubTypes.Type(value = VpnExitNode.class, name="verigraph.nodeTypes.VpnExit"),
+ @JsonSubTypes.Type(value = WebClientNode.class, name="verigraph.nodeTypes.WebClient"),
+ @JsonSubTypes.Type(value = WebServerNode.class, name="verigraph.nodeTypes.WebServer")
+})
+public class NodeTemplateYaml {
+ private String name;
+ private String type;
+
+ public String getName() {
+ return name;
+ }
+ public void setName(String name) {
+ this.name = name;
+ }
+ public String getType() {
+ return type;
+ }
+ public void setType(String type) {
+ this.type = type;
+ }
+
+ // //Generic YamlNode configuration to be extended in single nodes
+ // public interface ConfigurationYaml {
+ // }
+
+}
diff --git a/verigraph/src/it/polito/verigraph/tosca/yaml/beans/RelationshipTemplateYaml.java b/verigraph/src/it/polito/verigraph/tosca/yaml/beans/RelationshipTemplateYaml.java new file mode 100644 index 0000000..d828775 --- /dev/null +++ b/verigraph/src/it/polito/verigraph/tosca/yaml/beans/RelationshipTemplateYaml.java @@ -0,0 +1,30 @@ +/*******************************************************************************
+ * Copyright (c) 2018 Politecnico di Torino and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Apache License, Version 2.0
+ * which accompanies this distribution, and is available at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+package it.polito.verigraph.tosca.yaml.beans;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import java.util.Map;
+
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class RelationshipTemplateYaml {
+ private String type;
+ private Map<String, String> properties;
+ public String getType() {
+ return type;
+ }
+ public void setType(String type) {
+ this.type = type;
+ }
+ public Map<String, String> getProperties() {
+ return properties;
+ }
+ public void setProperties(Map<String, String> properties) {
+ this.properties = properties;
+ }
+}
diff --git a/verigraph/src/it/polito/verigraph/tosca/yaml/beans/ServiceTemplateYaml.java b/verigraph/src/it/polito/verigraph/tosca/yaml/beans/ServiceTemplateYaml.java new file mode 100644 index 0000000..0955a7d --- /dev/null +++ b/verigraph/src/it/polito/verigraph/tosca/yaml/beans/ServiceTemplateYaml.java @@ -0,0 +1,39 @@ +/*******************************************************************************
+ * Copyright (c) 2018 Politecnico di Torino and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Apache License, Version 2.0
+ * which accompanies this distribution, and is available at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+package it.polito.verigraph.tosca.yaml.beans;
+
+import java.util.Map;
+import com.fasterxml.jackson.annotation.*;
+
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class ServiceTemplateYaml {
+ private Map<String, String> metadata;
+ private String description;
+ private TopologyTemplateYaml topology_template;
+
+ public Map<String, String> getMetadata() {
+ return metadata;
+ }
+ public void setMetadata(Map<String, String> metadata) {
+ this.metadata = metadata;
+ }
+ public String getDescription() {
+ return description;
+ }
+ public void setDescription(String description) {
+ this.description = description;
+ }
+ public TopologyTemplateYaml getTopology_template() {
+ return topology_template;
+ }
+ public void setTopology_template(TopologyTemplateYaml topology_template) {
+ this.topology_template = topology_template;
+ }
+
+}
diff --git a/verigraph/src/it/polito/verigraph/tosca/yaml/beans/TopologyTemplateYaml.java b/verigraph/src/it/polito/verigraph/tosca/yaml/beans/TopologyTemplateYaml.java new file mode 100644 index 0000000..2653697 --- /dev/null +++ b/verigraph/src/it/polito/verigraph/tosca/yaml/beans/TopologyTemplateYaml.java @@ -0,0 +1,35 @@ +/*******************************************************************************
+ * Copyright (c) 2018 Politecnico di Torino and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Apache License, Version 2.0
+ * which accompanies this distribution, and is available at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+package it.polito.verigraph.tosca.yaml.beans;
+
+import java.util.Map;
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class TopologyTemplateYaml {
+ private Map<String, NodeTemplateYaml> node_templates;
+ private Map<String, RelationshipTemplateYaml> relationship_templates;
+
+ public Map<String, RelationshipTemplateYaml> getRelationship_templates() {
+ return relationship_templates;
+ }
+
+ public void setRelationship_templates(Map<String, RelationshipTemplateYaml> relationship_templates) {
+ this.relationship_templates = relationship_templates;
+ }
+
+ public Map<String, NodeTemplateYaml> getNode_templates() {
+ return node_templates;
+ }
+
+ public void setNode_templates(Map<String, NodeTemplateYaml> node_templates) {
+ this.node_templates = node_templates;
+ }
+
+}
diff --git a/verigraph/src/it/polito/verigraph/tosca/yaml/beans/VerificationYaml.java b/verigraph/src/it/polito/verigraph/tosca/yaml/beans/VerificationYaml.java new file mode 100644 index 0000000..2f572a6 --- /dev/null +++ b/verigraph/src/it/polito/verigraph/tosca/yaml/beans/VerificationYaml.java @@ -0,0 +1,58 @@ +/******************************************************************************* + * Copyright (c) 2018 Politecnico di Torino and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Apache License, Version 2.0 + * which accompanies this distribution, and is available at + * http://www.apache.org/licenses/LICENSE-2.0 + *******************************************************************************/ +package it.polito.verigraph.tosca.yaml.beans; + +import java.util.List; +import com.fasterxml.jackson.annotation.*; + +@JsonIgnoreProperties(ignoreUnknown = true) +public class VerificationYaml { + /* private Map<String, String> metadata; + private String description;*/ + private String result; + private String comment; + private List<ServiceTemplateYaml> paths; + + /* public Map<String, String> getMetadata() { + return metadata; + } + public void setMetadata(Map<String, String> metadata) { + this.metadata = metadata; + } + public String getDescription() { + return description; + } + public void setDescription(String description) { + this.description = description; + }*/ + public String getResult() { + return result; + } + + public void setResult(String result) { + this.result = result; + } + + public String getComment() { + return comment; + } + + public void setComment(String comment) { + this.comment = comment; + } + + public List<ServiceTemplateYaml> getPaths() { + return paths; + } + + public void setPaths(List<ServiceTemplateYaml> paths) { + this.paths = paths; + } + +}
\ No newline at end of file diff --git a/verigraph/src/it/polito/verigraph/tosca/yaml/beans/VpnAccessConfigurationYaml.java b/verigraph/src/it/polito/verigraph/tosca/yaml/beans/VpnAccessConfigurationYaml.java new file mode 100644 index 0000000..807059f --- /dev/null +++ b/verigraph/src/it/polito/verigraph/tosca/yaml/beans/VpnAccessConfigurationYaml.java @@ -0,0 +1,25 @@ +/*******************************************************************************
+ * Copyright (c) 2018 Politecnico di Torino and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Apache License, Version 2.0
+ * which accompanies this distribution, and is available at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+package it.polito.verigraph.tosca.yaml.beans;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class VpnAccessConfigurationYaml implements ConfigurationYaml {
+ private String vpnexit;
+
+ public String getVpnexit() {
+ return vpnexit;
+ }
+
+ public void setVpnexit(String vpnexit) {
+ this.vpnexit = vpnexit;
+ }
+
+}
diff --git a/verigraph/src/it/polito/verigraph/tosca/yaml/beans/VpnAccessNode.java b/verigraph/src/it/polito/verigraph/tosca/yaml/beans/VpnAccessNode.java new file mode 100644 index 0000000..9058615 --- /dev/null +++ b/verigraph/src/it/polito/verigraph/tosca/yaml/beans/VpnAccessNode.java @@ -0,0 +1,21 @@ +/*******************************************************************************
+ * Copyright (c) 2018 Politecnico di Torino and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Apache License, Version 2.0
+ * which accompanies this distribution, and is available at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+package it.polito.verigraph.tosca.yaml.beans;
+
+public class VpnAccessNode extends NodeTemplateYaml{
+ private VpnAccessConfigurationYaml properties;
+
+ public VpnAccessConfigurationYaml getProperties() {
+ return properties;
+ }
+
+ public void setProperties(VpnAccessConfigurationYaml properties) {
+ this.properties = properties;
+ }
+}
diff --git a/verigraph/src/it/polito/verigraph/tosca/yaml/beans/VpnExitConfigurationYaml.java b/verigraph/src/it/polito/verigraph/tosca/yaml/beans/VpnExitConfigurationYaml.java new file mode 100644 index 0000000..090e337 --- /dev/null +++ b/verigraph/src/it/polito/verigraph/tosca/yaml/beans/VpnExitConfigurationYaml.java @@ -0,0 +1,24 @@ +/*******************************************************************************
+ * Copyright (c) 2018 Politecnico di Torino and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Apache License, Version 2.0
+ * which accompanies this distribution, and is available at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+package it.polito.verigraph.tosca.yaml.beans;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class VpnExitConfigurationYaml implements ConfigurationYaml {
+ private String vpnaccess;
+
+ public String getVpnaccess() {
+ return vpnaccess;
+ }
+
+ public void setVpnaccess(String vpnaccess) {
+ this.vpnaccess = vpnaccess;
+ }
+}
diff --git a/verigraph/src/it/polito/verigraph/tosca/yaml/beans/VpnExitNode.java b/verigraph/src/it/polito/verigraph/tosca/yaml/beans/VpnExitNode.java new file mode 100644 index 0000000..775b8d3 --- /dev/null +++ b/verigraph/src/it/polito/verigraph/tosca/yaml/beans/VpnExitNode.java @@ -0,0 +1,22 @@ +/*******************************************************************************
+ * Copyright (c) 2018 Politecnico di Torino and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Apache License, Version 2.0
+ * which accompanies this distribution, and is available at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+package it.polito.verigraph.tosca.yaml.beans;
+
+public class VpnExitNode extends NodeTemplateYaml {
+ private VpnExitConfigurationYaml properties;
+
+ public VpnExitConfigurationYaml getProperties() {
+ return properties;
+ }
+
+ public void setProperties(VpnExitConfigurationYaml properties) {
+ this.properties = properties;
+ }
+
+}
diff --git a/verigraph/src/it/polito/verigraph/tosca/yaml/beans/WebClientConfigurationYaml.java b/verigraph/src/it/polito/verigraph/tosca/yaml/beans/WebClientConfigurationYaml.java new file mode 100644 index 0000000..02825ed --- /dev/null +++ b/verigraph/src/it/polito/verigraph/tosca/yaml/beans/WebClientConfigurationYaml.java @@ -0,0 +1,25 @@ +/*******************************************************************************
+ * Copyright (c) 2018 Politecnico di Torino and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Apache License, Version 2.0
+ * which accompanies this distribution, and is available at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+package it.polito.verigraph.tosca.yaml.beans;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class WebClientConfigurationYaml implements ConfigurationYaml{
+ private String nameWebServer;
+
+ public String getNameWebServer() {
+ return nameWebServer;
+ }
+
+ public void setNameWebServer(String nameWebServer) {
+ this.nameWebServer = nameWebServer;
+ }
+
+}
diff --git a/verigraph/src/it/polito/verigraph/tosca/yaml/beans/WebClientNode.java b/verigraph/src/it/polito/verigraph/tosca/yaml/beans/WebClientNode.java new file mode 100644 index 0000000..5e01194 --- /dev/null +++ b/verigraph/src/it/polito/verigraph/tosca/yaml/beans/WebClientNode.java @@ -0,0 +1,21 @@ +/*******************************************************************************
+ * Copyright (c) 2018 Politecnico di Torino and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Apache License, Version 2.0
+ * which accompanies this distribution, and is available at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+package it.polito.verigraph.tosca.yaml.beans;
+
+public class WebClientNode extends NodeTemplateYaml {
+ private WebClientConfigurationYaml properties;
+
+ public WebClientConfigurationYaml getProperties() {
+ return properties;
+ }
+
+ public void setProperties(WebClientConfigurationYaml properties) {
+ this.properties = properties;
+ }
+}
diff --git a/verigraph/src/it/polito/verigraph/tosca/yaml/beans/WebServerConfigurationYaml.java b/verigraph/src/it/polito/verigraph/tosca/yaml/beans/WebServerConfigurationYaml.java new file mode 100644 index 0000000..1f37c09 --- /dev/null +++ b/verigraph/src/it/polito/verigraph/tosca/yaml/beans/WebServerConfigurationYaml.java @@ -0,0 +1,24 @@ +/*******************************************************************************
+ * Copyright (c) 2018 Politecnico di Torino and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Apache License, Version 2.0
+ * which accompanies this distribution, and is available at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+package it.polito.verigraph.tosca.yaml.beans;
+
+import java.util.List;
+
+public class WebServerConfigurationYaml implements ConfigurationYaml{
+ public List<String> names;
+
+ public List<String> getNames() {
+ return names;
+ }
+
+ public void setNames(List<String> names) {
+ this.names = names;
+ }
+
+}
diff --git a/verigraph/src/it/polito/verigraph/tosca/yaml/beans/WebServerNode.java b/verigraph/src/it/polito/verigraph/tosca/yaml/beans/WebServerNode.java new file mode 100644 index 0000000..5340b77 --- /dev/null +++ b/verigraph/src/it/polito/verigraph/tosca/yaml/beans/WebServerNode.java @@ -0,0 +1,21 @@ +/*******************************************************************************
+ * Copyright (c) 2018 Politecnico di Torino and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Apache License, Version 2.0
+ * which accompanies this distribution, and is available at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *******************************************************************************/
+package it.polito.verigraph.tosca.yaml.beans;
+
+public class WebServerNode extends NodeTemplateYaml {
+ private WebServerConfigurationYaml properties;
+
+ public WebServerConfigurationYaml getProperties() {
+ return properties;
+ }
+
+ public void setProperties(WebServerConfigurationYaml properties) {
+ this.properties = properties;
+ }
+}
diff --git a/verigraph/src/main/proto/verigraph.proto b/verigraph/src/main/proto/verigraph.proto index feb8ff0..e8e9ccc 100644 --- a/verigraph/src/main/proto/verigraph.proto +++ b/verigraph/src/main/proto/verigraph.proto @@ -1,3 +1,13 @@ +/* This Protocol Buffer has been updated for supporting TOSCA-based objects. + * The only granularity for executing CRUD operations is at the TopologyTemplate level. + * + * The names of the objects are assigned according to the TOSCA standard, and can be + * mapped as follows in the Verigraph domain: + * TopologyTemplate -> Graph + * NodeTemplate -> Node + * RelationshipTemplate -> Neighbour (partial) +*/ + syntax = "proto3"; package verigraph; @@ -6,7 +16,7 @@ option java_multiple_files = true; option java_package = "it.polito.verigraph.grpc"; option java_outer_classname = "VerigraphProto"; -// The service definition. +/** gRPC */ service Verigraph { // Obtains a list of graphs rpc GetGraphs (GetRequest) returns (stream GraphGrpc) {} @@ -45,8 +55,24 @@ service Verigraph { rpc DeleteNeighbour (RequestID) returns (Status) {} // Updates a neighbour rpc UpdateNeighbour (NeighbourGrpc) returns (NewNeighbour) {} + + /** TOSCA gRPC */ + // Obtain a list of topology templates + rpc GetTopologyTemplates (GetRequest) returns (stream TopologyTemplateGrpc) {} + // Obtain a topology template + rpc GetTopologyTemplate (ToscaRequestID) returns (TopologyTemplateGrpc) {} + // Create a TopologyTemplate + rpc CreateTopologyTemplate (TopologyTemplateGrpc) returns (NewTopologyTemplate) {} + // Delete a TopologyTemplate + rpc DeleteTopologyTemplate (ToscaRequestID) returns (Status) {} + // Update a TopologyTemplate + rpc UpdateTopologyTemplate (TopologyTemplateGrpc) returns (NewTopologyTemplate) {} + // Verify a ToscaPolicy + rpc VerifyToscaPolicy (ToscaPolicy) returns (ToscaVerificationGrpc) {} } + +/** Messages */ message GetRequest { } @@ -151,4 +177,87 @@ string errorMessage = 5; message Status{ bool success = 1; string errorMessage = 2; -}
\ No newline at end of file +} + +/** TOSCA Messages */ +message ToscaRequestID { + string idTopologyTemplate = 1; +} + +message TopologyTemplateGrpc{ + string id = 1; + string name = 2; + repeated NodeTemplateGrpc nodeTemplate = 3; + repeated RelationshipTemplateGrpc relationshipTemplate = 4; + string errorMessage = 5; +} + +message NewTopologyTemplate{ + bool success = 1; + TopologyTemplateGrpc topologyTemplate = 2; + string errorMessage = 3; +} + +message NodeTemplateGrpc{ + string id = 1; + string name = 2; + enum Type { + antispam = 0; + cache = 1; + dpi = 2; + endhost = 3; + endpoint = 4; + fieldmodifier = 5; + firewall = 6; + mailclient = 7; + mailserver = 8; + nat = 9; + vpnaccess = 10; + vpnexit = 11; + webclient = 12; + webserver = 13; + } + Type type = 3; + ToscaConfigurationGrpc configuration = 4; + string errorMessage = 5; +} + +message RelationshipTemplateGrpc{ + string idSourceNodeTemplate = 1; + string idTargetNodeTemplate = 2; + string id = 3; + string name = 4; + string errorMessage = 5; +} + +message ToscaPolicy{ + string idTopologyTemplate = 1; + string source = 2; + string destination = 3; + enum PolicyType { + reachability = 0; + isolation = 1; + traversal = 2; + } + PolicyType type = 4; + string middlebox = 5; +} + +message ToscaConfigurationGrpc{ + string id = 1; + string description = 2; + string configuration = 3; +} + +message ToscaTestGrpc { + repeated NodeTemplateGrpc nodeTemplate = 1; + string result = 2; +} + +message ToscaVerificationGrpc{ + bool successOfOperation = 1; + string result = 2; + string comment = 3; + repeated ToscaTestGrpc test = 4; + string errorMessage = 5; +} |