camtool 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 3f150b39a20695aa69a3bde1a84e1f22f78e1fc007920b10a8a49c332c3d0512
4
+ data.tar.gz: 94f865410c2a203d77e4ca8fcbc3db3422b12e79412a9caf8cbed2ce06c86f2e
5
+ SHA512:
6
+ metadata.gz: 2c7c82e135f38b92b6fb70468c9fe42c4647e0fc3af17fd2208d38e4326e6f2e43d6d03965abc769341697181fbe6ebf498e1442a0013a7a33de9c809614a9ba
7
+ data.tar.gz: 187a61ec87799ac4c7e9546b624263a252948396d2a96fabd967313028fc6bd01629dd62893f0c126a13bb73acccf5e84d889754a1e71b7432cf46ce9e53f693
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ The MIT License
2
+
3
+ Copyright (c) 2015-2019 University of Bristol, University of Cambridge,
4
+ Harvard University, University of British Columbia http://camflow.org
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ of this software and associated documentation files (the "Software"), to deal
8
+ in the Software without restriction, including without limitation the rights
9
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ copies of the Software, and to permit persons to whom the Software is
11
+ furnished to do so, subject to the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be included in
14
+ all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
+ THE SOFTWARE.
@@ -0,0 +1,17 @@
1
+ # camflow-ruby
2
+
3
+ ```
4
+ sudo dnf install ruby ruby-devel redhat-rpm-config graphviz
5
+ ```
6
+
7
+ ```
8
+ gem install json rgl mqtt rake bundler
9
+ ```
10
+
11
+ ## install
12
+
13
+ ```
14
+ git clone https://github.com/tfjmp/camtool
15
+ cd camtool
16
+ rake install
17
+ ```
@@ -0,0 +1,42 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'camtool.rb'
4
+ require 'rgl/dot'
5
+ require 'rgl/topsort'
6
+ require 'rgl/transitivity'
7
+
8
+ instruction = ARGV[0]
9
+ target = ARGV[1]
10
+
11
+ if instruction == '--version' || instruction == '-v'
12
+ CamTool.version
13
+ elsif instruction == '--info'
14
+ print CamTool::ProvJSONtoRGL.new.read_log_file(target).information
15
+ CamTool::EdgeCounter.new.read_log_file(target).show
16
+ CamTool::VertexCounter.new.read_log_file(target).show
17
+ elsif instruction == '--publish'
18
+ CamTool::MQTTBreaker.new.break_log_file target
19
+ elsif instruction == '--break'
20
+ CamTool::LogBreaker.new.break_log_file target
21
+ elsif instruction == '--validate'
22
+ CamTool::ProvJSONtoRGL.new.read_log_file(target).validate
23
+ puts 'Graph structure verified...'
24
+ CamTool::EdgeValidator.new.read_log_file(target)
25
+ puts 'Relations verified...'
26
+ elsif instruction == '--packet'
27
+ CamTool::CheckPacket.new.read_log_file(target)
28
+ elsif instruction == '--png'
29
+ print CamTool::ProvJSONtoRGL.new.read_log_file(target).png
30
+ elsif instruction == '--list'
31
+ types = ARGV[2]
32
+ CamTool::ProvJSONtoRGL.new.read_log_file(target).list(types)
33
+ else
34
+ puts '--version'
35
+ puts '--info <path to log file>'
36
+ puts '--publish <path to log file>'
37
+ puts '--break <path to log file>'
38
+ puts '--png <path to log file>'
39
+ puts '--packet <path to log file>'
40
+ puts '--validate <path to log file>'
41
+ puts '--list <path to log file> [optional comma-separated list of element type e.g. "path,argv"]'
42
+ end
@@ -0,0 +1,9 @@
1
+ require 'camtool/provjson_parser'
2
+ require 'camtool/provjson_to_rgl'
3
+ require 'camtool/edge_counter'
4
+ require 'camtool/edge_validator'
5
+ require 'camtool/vertex_counter'
6
+ require 'camtool/log_breaker'
7
+ require 'camtool/check_packet.rb'
8
+ require 'camtool/breaker_mqtt'
9
+ require 'camtool/version'
@@ -0,0 +1,24 @@
1
+ require 'mqtt'
2
+ require 'zlib'
3
+ require 'base64'
4
+
5
+ module CamTool
6
+ class MQTTBreaker < LogBreaker
7
+ def initialize
8
+ conn_opts = {
9
+ remote_host: 'm12.cloudmqtt.com',
10
+ remote_port: 17065,
11
+ username: 'camflow',
12
+ password: 'test',
13
+ }
14
+ @c = MQTT::Client.connect conn_opts
15
+ end
16
+
17
+ def new_entry entry
18
+ comp = Zlib::Deflate.deflate entry
19
+ ready = Base64.encode64 comp
20
+ @c.publish 'camflow/test', ready
21
+ sleep 5
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,10 @@
1
+ module CamTool
2
+ class CheckPacket < ProvJSONParser
3
+ def initialize
4
+ end
5
+
6
+ def entity k, v
7
+ puts v['cf:jiffies']+"\t"+v['prov:label'] unless v['prov:type'] != 'packet'
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,41 @@
1
+ module CamTool
2
+ class EdgeCounter < ProvJSONParser
3
+ attr_reader :map
4
+
5
+ def initialize
6
+ @map = Hash.new(0)
7
+ end
8
+
9
+ def add key
10
+ @map[key]=@map[key]+1
11
+ end
12
+
13
+ def used k, v
14
+ self.add v['prov:type']
15
+ end
16
+
17
+ def wasGeneratedBy k, v
18
+ self.add v['prov:type']
19
+ end
20
+
21
+ def wasDerivedFrom k, v
22
+ self.add v['prov:type']
23
+ end
24
+
25
+ def wasInformedBy k, v
26
+ self.add v['prov:type']
27
+ end
28
+
29
+ def wasAssociatedWith k, v
30
+ self.add v['prov:type']
31
+ end
32
+
33
+ def show
34
+ puts "\n\n-------------\nEdge types\n-------------\n"
35
+ @map = @map.sort_by { |key, value| value }.reverse
36
+ @map.each do |key, value|
37
+ puts "#{key}:#{value}"
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,74 @@
1
+ module CamTool
2
+ class EdgeValidator < ProvJSONParser
3
+ def initialize
4
+ end
5
+
6
+ def print_relation_bytes id
7
+ id = id.gsub 'cf:', ''
8
+ bytes = Base64.decode64(id).bytes.to_a
9
+ type = bytes[7] & 0xF0
10
+ puts type.to_s(16)
11
+ type = bytes[8]
12
+ puts type.to_s(16)
13
+ end
14
+
15
+ def is_relation? id
16
+ id = id.gsub 'cf:', ''
17
+ bytes = Base64.decode64(id).bytes.to_a
18
+ type = bytes[7] & 0xF0
19
+ return type == 0x80
20
+ end
21
+
22
+ def is_activity? id
23
+ id = id.gsub 'cf:', ''
24
+ bytes = Base64.decode64(id).bytes.to_a
25
+ type = bytes[7] & 0xF0
26
+ return type == 0x40
27
+ end
28
+
29
+ def is_entity? id
30
+ id = id.gsub 'cf:', ''
31
+ bytes = Base64.decode64(id).bytes.to_a
32
+ type = bytes[7] & 0xF0
33
+ return type == 0x20
34
+ end
35
+
36
+ def is_agent? id
37
+ id = id.gsub 'cf:', ''
38
+ bytes = Base64.decode64(id).bytes.to_a
39
+ type = bytes[7] & 0xF0
40
+ return type == 0x10
41
+ end
42
+
43
+ def used k, v
44
+ abort "used prov:entity is of wrong type: #{v}." unless is_entity? v['prov:entity']
45
+ abort "used prov:activity is of wrong type: #{v}." unless is_activity? v['prov:activity']
46
+ end
47
+
48
+ def wasGeneratedBy k, v
49
+ abort "wasGeneratedBy prov:entity is of wrong type: #{v}." unless is_entity? v['prov:entity']
50
+ abort "wasGeneratedBy prov:activity is of wrong type: #{v}." unless is_activity? v['prov:activity']
51
+ end
52
+
53
+ def wasDerivedFrom k, v
54
+ abort "wasDerivedFrom prov:usedEntity is of wrong type: #{v}." unless is_entity? v['prov:usedEntity']
55
+ abort "wasDerivedFrom prov:generatedEntity is of wrong type: #{v}." unless is_entity? v['prov:generatedEntity']
56
+ end
57
+
58
+ def wasInformedBy k, v
59
+ abort "wasInformedBy prov:informant is of wrong type: #{v}." unless is_activity? v['prov:informant']
60
+ abort "wasInformedBy prov:informed is of wrong type: #{v}." unless is_activity? v['prov:informed']
61
+ end
62
+
63
+ def wasAssociatedWith k, v
64
+ abort "wasAssociatedWith prov:activity is of wrong type: #{v}." unless is_activity? v['prov:activity']
65
+ abort "wasAssociatedWith prov:agent is of wrong type: #{v}." unless is_agent? v['prov:agent']
66
+ end
67
+
68
+ def relation k, v
69
+ print_relation_bytes k
70
+ puts v
71
+ abort "relation should not be used"
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,32 @@
1
+ module CamTool
2
+ class LogBreaker
3
+ def break_log_file filename
4
+ if filename != nil
5
+ open(filename) do |file|
6
+ @i=0
7
+ file.each_line do |line|
8
+ ok = true
9
+ line = line.sub /\[[0-9 :-]*\]\t[A-Z]*[ ]*:[ ]*/, ''
10
+ line = line.gsub "\n", ''
11
+ begin
12
+ JSON.parse(line)
13
+ rescue JSON::ParserError
14
+ abort "Error #{ex.class}, message: #{ex.message}"
15
+ end
16
+ self.new_entry line unless !ok
17
+ end
18
+ end unless !File.file?(filename)
19
+ print "File does not exist\n" unless File.file?(filename)
20
+ end
21
+ self
22
+ end
23
+
24
+ def new_entry entry
25
+ fname="./#{@i}.break"
26
+ @i=@i+1
27
+ File.open(fname, 'w+') do |f|
28
+ f.write entry
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,104 @@
1
+ require 'json'
2
+
3
+ module CamTool
4
+ class ProvJSONParser
5
+ def read_json_file filename
6
+ if filename != nil
7
+ parse_json File.read(filename).gsub("\n", '') unless !File.file?(filename)
8
+ print "File does not exist\n" unless File.file?(filename)
9
+ end
10
+ self
11
+ end
12
+
13
+ def read_log_file filename
14
+ if filename != nil
15
+ open(filename) do |file|
16
+ file.each_line do |line|
17
+ parse_json line.gsub("\n", '')
18
+ end
19
+ end unless !File.file?(filename)
20
+ print "File does not exist\n" unless File.file?(filename)
21
+ end
22
+ self
23
+ end
24
+
25
+ def used k, v
26
+ end
27
+
28
+ def wasGeneratedBy k, v
29
+ end
30
+
31
+ def wasDerivedFrom k, v
32
+ end
33
+
34
+ def wasInformedBy k, v
35
+ end
36
+
37
+ def wasAssociatedWith k, v
38
+ end
39
+
40
+ def relation k, v
41
+ end
42
+
43
+ def prefix k, v
44
+ end
45
+
46
+ def entity k, v
47
+ end
48
+
49
+ def activity k, v
50
+ end
51
+
52
+ def agent k, v
53
+ end
54
+
55
+ def parse_json string
56
+ begin
57
+ json = JSON.parse(string)
58
+ rescue JSON::ParserError => ex
59
+ puts "Length: #{string.length}\n"
60
+ abort "Error #{ex.class}, message: #{ex.message}"
61
+ end
62
+
63
+ json['prefix'].each do |k, v|
64
+ self.prefix k, v
65
+ end unless !json.key? 'prefix'
66
+
67
+ json['entity'].each do |k, v|
68
+ self.entity k, v
69
+ end unless !json.key? 'entity'
70
+
71
+ json['activity'].each do |k, v|
72
+ self.activity k, v
73
+ end unless !json.key? 'activity'
74
+
75
+ json['agent'].each do |k, v|
76
+ self.activity k, v
77
+ end unless !json.key? 'agent'
78
+
79
+ json['used'].each do |k, v|
80
+ self.used k, v
81
+ end unless !json.key? 'used'
82
+
83
+ json['wasGeneratedBy'].each do |k, v|
84
+ self.wasGeneratedBy k, v
85
+ end unless !json.key? 'wasGeneratedBy'
86
+
87
+ json['wasDerivedFrom'].each do |k, v|
88
+ self.wasDerivedFrom k, v
89
+ end unless !json.key? 'wasDerivedFrom'
90
+
91
+ json['wasInformedBy'].each do |k, v|
92
+ self.wasInformedBy k, v
93
+ end unless !json.key? 'wasInformedBy'
94
+
95
+ json['relation'].each do |k, v|
96
+ self.relation k, v
97
+ end unless !json.key? 'relation'
98
+
99
+ json['wasAssociatedWith'].each do |k, v|
100
+ self.wasAssociatedWith k, v
101
+ end unless !json.key? 'wasAssociatedWith'
102
+ end
103
+ end
104
+ end
@@ -0,0 +1,103 @@
1
+ require 'rgl/adjacency'
2
+ require 'rgl/dot'
3
+ require 'rgl/topsort'
4
+ require 'rgl/transitivity'
5
+
6
+ module CamTool
7
+ class ProvJSONtoRGL < ProvJSONParser
8
+ attr_reader :dg
9
+ attr_reader :map
10
+ attr_reader :edges
11
+
12
+ def initialize
13
+ @dg = RGL::DirectedAdjacencyGraph.new # initialise the graph structure
14
+ @map = Hash.new
15
+ @edges = Hash.new
16
+ end
17
+
18
+ def entity k, v
19
+ @map[k] = v
20
+ end
21
+
22
+ def activity k, v
23
+ @map[k] = v
24
+ end
25
+
26
+ def agent k, v
27
+ @map[k] = v
28
+ end
29
+
30
+ def used k, v
31
+ @dg.add_edge v['prov:activity'], v['prov:entity']
32
+ @edges[v['prov:activity']+v['prov:entity']] = v
33
+ end
34
+
35
+ def wasGeneratedBy k, v
36
+ @dg.add_edge v['prov:entity'], v['prov:activity']
37
+ @edges[v['prov:entity']+v['prov:activity']] = v
38
+ end
39
+
40
+ def wasDerivedFrom k, v
41
+ @dg.add_edge v['prov:generatedEntity'], v['prov:usedEntity']
42
+ @edges[v['prov:generatedEntity']+v['prov:usedEntity']] = v
43
+ end
44
+
45
+ def wasInformedBy k, v
46
+ @dg.add_edge v['prov:informed'], v['prov:informant']
47
+ @edges[v['prov:informed']+v['prov:informant']] = v
48
+ end
49
+
50
+ def wasAssociatedWith k, v
51
+ @dg.add_edge v['prov:activity'], v['prov:agent']
52
+ @edges[v['prov:activity']+v['prov:agent']] = v
53
+ @dg.add_edge v['prov:agent'], v['prov:plan'] unless !v.key? 'prov:plan'
54
+ end
55
+
56
+ def information
57
+ str = "Graph:\n"
58
+ if @dg.directed?
59
+ str += "directed\n"
60
+ else
61
+ str += "not directed\n"
62
+ end
63
+
64
+ if @dg.acyclic?
65
+ str += "acyclic\n"
66
+ else
67
+ str += "not acyclic\n"
68
+ end
69
+
70
+ str += @dg.num_edges.to_s() +" edges.\n"
71
+ str += @dg.num_vertices.to_s() +" vertices.\n"
72
+ str += (@dg.num_edges.to_f/@dg.num_vertices).to_s() + " edges/vertices ratio.\n"
73
+ end
74
+
75
+ def validate
76
+ abort 'Graph is not directed!' unless @dg.directed?
77
+ abort 'Graph is not acyclic!' unless @dg.acyclic?
78
+ end
79
+
80
+ def svg
81
+ @dg.write_to_graphic_file('svg')
82
+ end
83
+
84
+ def jpg
85
+ @dg.write_to_graphic_file('jpg')
86
+ end
87
+
88
+ def png
89
+ @dg.write_to_graphic_file('png')
90
+ end
91
+
92
+ def list types
93
+ a = @dg.topsort_iterator.to_a
94
+ a_type = types.split(',')
95
+ a.each do |v|
96
+ if a_type.include?(@map[v]['prov:type']) || types.nil?
97
+ puts v + ' ' + @map[v]['prov:label'] unless @map[v]['prov:label'].nil?
98
+ puts v + ' no label' unless !@map[v]['prov:label'].nil?
99
+ end
100
+ end
101
+ end
102
+ end
103
+ end
@@ -0,0 +1,7 @@
1
+ module CamTool
2
+ VERSION = "0.1.0"
3
+
4
+ def self.version
5
+ puts VERSION
6
+ end
7
+ end
@@ -0,0 +1,33 @@
1
+ module CamTool
2
+ class VertexCounter < ProvJSONParser
3
+ attr_reader :map
4
+
5
+ def initialize
6
+ @map = Hash.new(0)
7
+ end
8
+
9
+ def add key
10
+ @map[key]=@map[key]+1
11
+ end
12
+
13
+ def entity k, v
14
+ self.add v['prov:type']
15
+ end
16
+
17
+ def activity k, v
18
+ self.add v['prov:type']
19
+ end
20
+
21
+ def agent k, v
22
+ self.add v['prov:type']
23
+ end
24
+
25
+ def show
26
+ puts "\n\n-------------\nVertex types\n-------------\n"
27
+ @map = @map.sort_by { |key, value| value }.reverse
28
+ @map.each do |key, value|
29
+ puts "#{key}:#{value}"
30
+ end
31
+ end
32
+ end
33
+ end
metadata ADDED
@@ -0,0 +1,142 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: camtool
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Thomas Pasquier
8
+ - Xuehuan "Michael" Han
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2019-01-21 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rgl
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - ">="
19
+ - !ruby/object:Gem::Version
20
+ version: '0.5'
21
+ type: :runtime
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ version: '0.5'
28
+ - !ruby/object:Gem::Dependency
29
+ name: rinruby
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: '2.0'
35
+ type: :runtime
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ version: '2.0'
42
+ - !ruby/object:Gem::Dependency
43
+ name: json
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ version: '2.1'
49
+ type: :runtime
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: '2.1'
56
+ - !ruby/object:Gem::Dependency
57
+ name: mqtt
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: '0.5'
63
+ type: :runtime
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: '0.5'
70
+ - !ruby/object:Gem::Dependency
71
+ name: bundler
72
+ requirement: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ version: '1.16'
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ version: '1.16'
84
+ - !ruby/object:Gem::Dependency
85
+ name: rake
86
+ requirement: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - ">="
89
+ - !ruby/object:Gem::Version
90
+ version: '10.0'
91
+ type: :development
92
+ prerelease: false
93
+ version_requirements: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - ">="
96
+ - !ruby/object:Gem::Version
97
+ version: '10.0'
98
+ description: Allow to test, publish and manipulate camflow log files.
99
+ email:
100
+ - tfjmp@seas.harvard.edu
101
+ executables:
102
+ - camtool
103
+ extensions: []
104
+ extra_rdoc_files: []
105
+ files:
106
+ - LICENSE
107
+ - README.md
108
+ - bin/camtool
109
+ - lib/camtool.rb
110
+ - lib/camtool/breaker_mqtt.rb
111
+ - lib/camtool/check_packet.rb
112
+ - lib/camtool/edge_counter.rb
113
+ - lib/camtool/edge_validator.rb
114
+ - lib/camtool/log_breaker.rb
115
+ - lib/camtool/provjson_parser.rb
116
+ - lib/camtool/provjson_to_rgl.rb
117
+ - lib/camtool/version.rb
118
+ - lib/camtool/vertex_counter.rb
119
+ homepage: https://github.com/tfjmp/camtool
120
+ licenses:
121
+ - MIT
122
+ metadata: {}
123
+ post_install_message:
124
+ rdoc_options: []
125
+ require_paths:
126
+ - lib
127
+ required_ruby_version: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ required_rubygems_version: !ruby/object:Gem::Requirement
133
+ requirements:
134
+ - - ">="
135
+ - !ruby/object:Gem::Version
136
+ version: '0'
137
+ requirements: []
138
+ rubygems_version: 3.0.2
139
+ signing_key:
140
+ specification_version: 4
141
+ summary: Tool to manipulate CamFlow log files.
142
+ test_files: []