b942442a07dc986896f3cce476fc953ce6c5edf3
[dcaegen2/platform/cli.git] / dcae-cli / dcae_cli / commands / data_format / commands.py
1 # ============LICENSE_START=======================================================
2 # org.onap.dcae
3 # ================================================================================
4 # Copyright (c) 2017 AT&T Intellectual Property. All rights reserved.
5 # ================================================================================
6 # Licensed under the Apache License, Version 2.0 (the "License");
7 # you may not use this file except in compliance with the License.
8 # You may obtain a copy of the License at
9 #
10 #      http://www.apache.org/licenses/LICENSE-2.0
11 #
12 # Unless required by applicable law or agreed to in writing, software
13 # distributed under the License is distributed on an "AS IS" BASIS,
14 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 # See the License for the specific language governing permissions and
16 # limitations under the License.
17 # ============LICENSE_END=========================================================
18 #
19 # ECOMP is a trademark and service mark of AT&T Intellectual Property.
20
21 # -*- coding: utf-8 -*-
22 """
23 Provides data format commands
24 """
25 import json
26
27 import click
28
29 import genson
30
31 import sys
32
33 import os
34
35 from jsonschema import Draft4Validator
36
37 from dcae_cli.util import load_json
38 from dcae_cli.util.logger import get_logger
39
40 from dcae_cli.commands import util
41 from dcae_cli.commands.util import create_table, parse_input
42
43 from dcae_cli.catalog.exc import MissingEntry
44 from dcae_cli.catalog.exc import DcaeException
45
46
47 logger = get_logger('DataFormatCommand')
48
49
50 @click.group()
51 def data_format():
52     pass
53
54
55 @data_format.command()
56 @click.option('--update', is_flag=True, help='Updates a locally added data format if it has not been already pushed')
57 @click.argument('specification', type=click.Path(resolve_path=True, exists=True))
58 @click.pass_obj
59 def add(obj, update, specification):
60     '''Tracks a data format file SPECIFICATION locally but does not push to the catalog'''
61     spec = load_json(specification)
62     user, catalog = obj['config']['user'], obj['catalog']
63     catalog.add_format(spec, user, update)
64
65
66 @data_format.command(name='list')
67 @click.option('--latest', is_flag=True, help='Only list the latest version of data formats')
68 @click.pass_obj
69 def list_format(obj, latest):
70     """Lists all your data formats"""
71     user, catalog = obj['config']['user'], obj['catalog']
72     dfs = catalog.list_formats(latest, user=user)
73
74     def format_record(df):
75         return (df["name"], df["version"],
76                 util.format_description(df["description"]),
77                 util.get_status_string(df), df["modified"])
78
79     dfs = [ format_record(df) for df in dfs ]
80
81     click.echo("")
82     click.echo("Data formats for {0}".format(user))
83     click.echo(create_table(('Name', 'Version', 'Description', 'Status', 'Modified'), dfs))
84
85
86 @data_format.command()
87 @click.argument('data-format', metavar="name:version")
88 @click.pass_obj
89 def show(obj, data_format):
90     '''Provides more information about FORMAT'''
91     name, ver = parse_input(data_format)
92     spec = obj['catalog'].get_format_spec(name, ver)
93
94     click.echo(util.format_json(spec))
95
96
97 @data_format.command()
98 @click.argument('data-format')
99 @click.pass_obj
100 def publish(obj, data_format):
101     """Publishes data format to make publicly available"""
102     name, version = parse_input(data_format)
103     user, catalog = obj['config']['user'], obj['catalog']
104
105     if catalog.publish_format(user, name, version):
106         click.echo("Data format has been published")
107     else:
108         click.echo("Data format could not be published")
109
110 @data_format.command()
111 @click.option('--keywords', is_flag=True, help='Adds a template of possible descriptive keywords', default=False)
112 @click.argument('name_version', metavar="name:version",  required = True)
113 @click.argument('file-or-dir-path', type=click.Path(resolve_path=True, exists=True, dir_okay=True, file_okay=True, readable=True),   metavar="file-or-dir-path")
114 @click.pass_obj
115 def generate(obj, name_version, file_or_dir_path, keywords):
116     '''Create schema from a file or directory examples'''
117     name, version = parse_input(name_version)
118     if version == None: 
119       version = ""
120     schema = genson.Schema()
121     if os.path.isfile(file_or_dir_path):
122       addfile(file_or_dir_path, schema)
123     else:
124       foundJSON = False
125       for root, dirs, files in os.walk(file_or_dir_path):
126           for filename in files:
127             fullfilename = os.path.join(file_or_dir_path, filename)
128             addfile(fullfilename,schema)
129             foundJSON = True
130       if foundJSON == False:
131         raise DcaeException('No JSON files found in ' + file_or_dir_path)
132
133     json_obj = json.loads(schema.to_json())
134     json_obj['$schema'] = "http://json-schema.org/draft-04/schema#"
135     jschema = json.dumps(json_obj)
136     jschema = jschema.replace('"required":', '"additionalproperties": true, "required":')
137     jschema = jschema.replace('"type":', ' "description": "", "type":')
138
139     if (keywords):
140       jschema = jschema.replace('"type": "string"', ' "maxLength": 0, "minLength": 0, "pattern": "", "type": "string"')
141       jschema = jschema.replace('"type": "integer"', ' "maximum": 0, "mininimum": 0, "multipleOf": 0, "type": "integer"')
142       jschema = jschema.replace('"type": "array"', ' "maxItems": 0, "minItems": 0, "uniqueItems": "false", "type": "array"')
143
144     jschema = '{ "self": { "name": "' + name + '", "version": "' + version + '", "description": ""} , "dataformatversion": "1.0.0", "jsonschema": ' + jschema + '}'
145     #Draft4Validator.check_schema(json.loads(jschema))
146     try:
147       print(json.dumps(json.loads(jschema), sort_keys=True, indent=4 ))
148     except ValueError:
149       raise DcaeException('Problem with JSON generation')
150
151 def addfile(filename, schema):
152   try: 
153     fileadd = open(filename, "r")
154   except IOError:
155     raise DcaeException('Cannot open' + filename)
156   try: 
157     json_object = json.loads(fileadd.read())
158     schema.add_object(json_object)
159   except ValueError:
160     raise DcaeException('Bad JSON file: ' + filename)
161   finally:
162     fileadd.close()
163
164