blob: b17c6a99594af36279b0eab730dabc0daeae0dca [file] [log] [blame]
Matteo Scandolo48d3d2d2017-08-08 13:05:27 -07001
2# Copyright 2017-present Open Networking Foundation
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15
16
Chetan Gaonkercfcce782016-05-10 10:10:42 -070017#
18# Copyright 2016-present Ciena Corporation
19#
20# Licensed under the Apache License, Version 2.0 (the "License");
21# you may not use this file except in compliance with the License.
22# You may obtain a copy of the License at
23#
24# http://www.apache.org/licenses/LICENSE-2.0
25#
26# Unless required by applicable law or agreed to in writing, software
27# distributed under the License is distributed on an "AS IS" BASIS,
28# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
29# See the License for the specific language governing permissions and
30# limitations under the License.
31#
A R Karthicka2e53d62016-02-19 17:38:30 -080032
33import yaml, pprint, sys, pdb
A R Karthicka2e53d62016-02-19 17:38:30 -080034
35stateHash = {}
A R Karthick85ed65e2016-02-22 09:49:57 -080036header = '''#!/usr/bin/env python
A R Karthicka2e53d62016-02-19 17:38:30 -080037'''
A R Karthicka2e53d62016-02-19 17:38:30 -080038# ---------------------------- DOT -----------------------------------
39colorList = ['aquamarine4', 'crimson', 'chartreuse4', 'darkolivegreen', 'darkgoldenrod', 'dodgerblue3', 'blue4', 'cyan4']
40rankdict = {}
41# ---------------------------- DOT -----------------------------------
42
A R Karthicka2e53d62016-02-19 17:38:30 -080043if __name__ == '__main__':
44
45 usage = ''
A R Karthicka2e53d62016-02-19 17:38:30 -080046 from optparse import OptionParser
A R Karthicka2e53d62016-02-19 17:38:30 -080047 parser = OptionParser(usage)
A R Karthicka2e53d62016-02-19 17:38:30 -080048 parser.add_option('-p', '--prefix', dest='prefix', type='string', action='store', help='prefix for state table')
49 parser.add_option('-f', '--file', dest='file', type='string', action='store', help='input yaml filename')
50 parser.add_option('-d', '--dot', dest='dot', default=False, action='store_true', help='output DOT')
A R Karthicka2e53d62016-02-19 17:38:30 -080051 (opts, args) = parser.parse_args()
A R Karthicka2e53d62016-02-19 17:38:30 -080052 prefix = opts.prefix
A R Karthicka2e53d62016-02-19 17:38:30 -080053 f = open(opts.file, 'r')
54 y = yaml.load(f)
55 f.close()
A R Karthicka2e53d62016-02-19 17:38:30 -080056 stateHash = y['States']
A R Karthicka2e53d62016-02-19 17:38:30 -080057 eventHash = {}
A R Karthicka2e53d62016-02-19 17:38:30 -080058 # GLOBAL DOT DIRECTIVES
59 stateRadiate = y.get('DOT_StateRadiate')
60 ignoredIntensity = abs(int(y.get('DOT_IgnoredIntensity', 100)) - 100)
61 eventGroups = y.get('DOT_EventGroups')
A R Karthicka2e53d62016-02-19 17:38:30 -080062 if stateRadiate is not None:
63 stateRadiate = str(stateRadiate)
64
65 actionStrLen = [0]
66 stateColorIdx = 0
67 for k, v in stateHash.iteritems():
68 events = v.get('Events')
69 if events:
70 for event in events.keys():
71 eventHash[event] = {}
A R Karthicka2e53d62016-02-19 17:38:30 -080072 actionStr = ''
A R Karthicka2e53d62016-02-19 17:38:30 -080073 for ev in events.values():
74 if ev.get('Actions'):
75 actionStr = ','.join(['obj.%s' % action for action in ev['Actions']]) + ','
76 actionStrLen.append(len(actionStr))
77
A R Karthicka2e53d62016-02-19 17:38:30 -080078 ievents = v.get('IgnoredEvents')
79 if ievents:
80 for event in ievents.keys():
81 eventHash[event] = {}
82
83 # ---------------------------- DOT -----------------------------------
A R Karthicka2e53d62016-02-19 17:38:30 -080084 # rankdict setup
85 rank = v.get('DOT_Rank')
86 if rank:
87 print >>sys.stderr, '%s rank %s' % (k, str(rank))
88 rankdict.setdefault(rank, []).append(k)
89
90 # assign a possible color if not specified
91 color = v.get('DOT_Color')
92 if color:
93 print >>sys.stderr, 'using user assigned color %s for %s' % (color, k)
94 else:
95 if stateRadiate and stateRadiate.lower() == 'auto':
96 color = colorList[stateColorIdx % len(colorList)]
97 stateColorIdx+= 1
98 else:
99 color = 'black'
100
101 stateHash[k]['DOT_Color'] = color
A R Karthicka2e53d62016-02-19 17:38:30 -0800102 # ---------------------------- DOT -----------------------------------
103
104 # ---------------------------- DOT -----------------------------------
105 # update the event hash with information from the event groups (if present)
106 if eventGroups:
107 for group in eventGroups.values():
108 for event in group['Events'].keys():
109 for attr, val in group['Attrs'].iteritems():
110 eventHash[event][attr] = val
111 print >>sys.stderr, 'assigning event group attr event %s attr %s val %s' % (event, attr, val)
112 # ---------------------------- DOT -----------------------------------
A R Karthicka2e53d62016-02-19 17:38:30 -0800113
114 maxStateLen = reduce(max, [len(x) for x in stateHash.keys()]) + 5 + len(prefix)
115 maxEventLen = reduce(max, [len(x) for x in eventHash.keys()]) + 5 + len(prefix)
116 maxActionLen = reduce(max, actionStrLen) + 5
117
118 if opts.dot:
A R Karthicka2e53d62016-02-19 17:38:30 -0800119 print 'digraph G {'
120 print ' edge [fontname="Tahoma", fontsize="10", minlen=2];'
121 print ' node [fontname="Tahoma", fontsize="10"];'
122 print ' graph [fontname="Tahoma", label="%s"];' % prefix
A R Karthicka2e53d62016-02-19 17:38:30 -0800123 print >>sys.stderr, 'stateRadiate:%s\nignoredIntensity:%d' % (stateRadiate, ignoredIntensity)
124
125 # emit state declarations
126 for state in stateHash.keys():
127 print ' %s[color="%s"];' % (state, stateHash[state]['DOT_Color'])
128
129 # emit rankings
130 for k, v in rankdict.iteritems():
131 print >>sys.stderr, '%s rank %s' % (k, str(v))
132
133 print 'subgraph { rank = same;'
134 for state in v:
135 print ' %s;' % state
136 print '}'
137
138 for state, va in stateHash.iteritems():
A R Karthicka2e53d62016-02-19 17:38:30 -0800139 # emit ignored events
140 if va.get('IgnoredEvents'):
141 for event, v in va['IgnoredEvents'].iteritems():
142 stateStr = state
143 eventStr = event
A R Karthicka2e53d62016-02-19 17:38:30 -0800144 print '%s -> %s [label="%s/",minlen=1, fontcolor="grey%d", color="grey%d"];' % (stateStr, stateStr, eventStr, ignoredIntensity, ignoredIntensity)
145
146 # emit transitions
147 if va.get('Events'):
148 for event, v in va['Events'].iteritems():
149 stateStr = state
150 eventStr = event
151 actionStr = ''
152 if v.get('Actions'):
153 actionStr = '\\n'.join([a.strip('_') for a in v['Actions']])
154 nextStr = v['NextState']
A R Karthicka2e53d62016-02-19 17:38:30 -0800155 labelStr = '%s/\\n%s' % (eventStr, actionStr)
A R Karthicka2e53d62016-02-19 17:38:30 -0800156 if stateRadiate:
157 color = va['DOT_Color']
158 elif len(eventHash[event]):
159 color = eventHash[event]['Color']
160 else:
161 color = 'black'
162
163 fontColor = color
A R Karthicka2e53d62016-02-19 17:38:30 -0800164 styleStr = ''
165 style = eventHash[event].get('Style')
166 if style:
167 styleStr = ',style="%s"' % (style)
168
169 if style == 'invis':
170 fontColor = 'white'
171
172 print '%s -> %s [label="%s", color="%s", fontcolor="%s" %s];' % (stateStr, nextStr, labelStr, color, fontColor, styleStr)
173
174 print
175
176 print '}'
177
A R Karthicka2e53d62016-02-19 17:38:30 -0800178 else:
179
180### emit it
181
182 print header
183
184### enumerations
185 '''
186 print '%sSt = Enumeration("%sState",(' % (prefix, prefix)
187 for state in stateHash.keys():
188 print '%s"%s",' % (' '*12, state)
189 print '%s))' % (' '*12)
190
191 print
192
193 print '%sEv = Enumeration("%sEvent",(' % (prefix, prefix)
194 for event in eventHash.keys():
195 print '%s"%s",' % (' '*12, event)
196 print '%s))' % (' '*12)
197 '''
A R Karthicka2e53d62016-02-19 17:38:30 -0800198### table
199
200 fmt = ' (%' + '-%d.%ds' % (maxStateLen, maxStateLen) + '%' + '-%d.%ds' % (maxEventLen, maxEventLen) + '):( %' +' -%d.%ds' % (maxActionLen, maxActionLen) + '%s),'
201 cfmt= ' ## %' + '-%d.%ds' % (maxStateLen, maxStateLen) + '%' + '-%d.%ds' % (maxEventLen, maxEventLen) + ' %' +' -%d.%ds' % (maxActionLen, maxActionLen) + '%s'
202
203 print 'def init%s%sFsmTable(obj,St,Ev):' % (prefix[0].upper(), prefix[1:])
204# print " %sFsmTable = {" % prefix
205 print " return {"
206 print
207
208 for state, va in stateHash.iteritems():
209
210 print cfmt % ('CurrentState', 'Event', 'Actions', 'NextState')
211 print
212
213 if va.get('IgnoredEvents'):
214 for event, v in va['IgnoredEvents'].iteritems():
215 stateStr = '%sSt.' % ('') + state + ','
216 eventStr = '%sEv.' % ('') + event
217
218 print fmt % (stateStr, eventStr, '(),', stateStr.strip(','))
219
220 if va.get('Events'):
221 for event, v in va['Events'].iteritems():
222 stateStr = '%sSt.' % ('') + state + ','
223 eventStr = '%sEv.' % ('') + event
224 actionStr = ''
225 if v.get('Actions'):
226 actionStr = ','.join(['obj.%s' % action for action in v['Actions']]) + ','
227
228 nextStr = '%sSt.' % ('') + v['NextState']
229
230 print fmt % (stateStr, eventStr, '(%s),' % actionStr , nextStr)
231
232 print
233
234 print "}"
235 print
236
237