omf_sfa 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (152) hide show
  1. data/.gitignore +24 -0
  2. data/Gemfile +6 -0
  3. data/README.md +211 -0
  4. data/Rakefile +23 -0
  5. data/bin/parse_rspec.rb +167 -0
  6. data/etc/omf-sfa/omf-sfa-am.yaml +12 -0
  7. data/examples/exogeni5nodemanifest.rspec +105 -0
  8. data/examples/instageni5nodemanifest.rspec +150 -0
  9. data/lib/omf-sfa/am/am-rest/REST_API.md +301 -0
  10. data/lib/omf-sfa/am/am-rest/account_handler.rb +145 -0
  11. data/lib/omf-sfa/am/am-rest/am_rest_server.rb +255 -0
  12. data/lib/omf-sfa/am/am-rest/api_template.html +48 -0
  13. data/lib/omf-sfa/am/am-rest/config.ru +110 -0
  14. data/lib/omf-sfa/am/am-rest/resource_handler.rb +178 -0
  15. data/lib/omf-sfa/am/am-rest/rest_handler.rb +573 -0
  16. data/lib/omf-sfa/am/am-rest/session_authenticator.rb +130 -0
  17. data/lib/omf-sfa/am/am-rpc/abstract_rpc_service.rb +60 -0
  18. data/lib/omf-sfa/am/am-rpc/am_authorizer.rb +161 -0
  19. data/lib/omf-sfa/am/am-rpc/am_rpc_api.rb +450 -0
  20. data/lib/omf-sfa/am/am-rpc/am_rpc_service.rb +402 -0
  21. data/lib/omf-sfa/am/am_liaison.rb +93 -0
  22. data/lib/omf-sfa/am/am_manager.rb +859 -0
  23. data/lib/omf-sfa/am/am_runner.rb +108 -0
  24. data/lib/omf-sfa/am/am_scheduler.rb +146 -0
  25. data/lib/omf-sfa/am/am_server.rb +194 -0
  26. data/lib/omf-sfa/am/config.ru +122 -0
  27. data/lib/omf-sfa/am/credential.rb +145 -0
  28. data/lib/omf-sfa/am/default_authorizer.rb +44 -0
  29. data/lib/omf-sfa/am/privilege_credential.rb +76 -0
  30. data/lib/omf-sfa/am/signature.rb +37 -0
  31. data/lib/omf-sfa/am/user_credential.rb +56 -0
  32. data/lib/omf-sfa/am.rb +7 -0
  33. data/lib/omf-sfa/model/abstract_prop_description.rb +87 -0
  34. data/lib/omf-sfa/model/model_class_description.rb +145 -0
  35. data/lib/omf-sfa/model/model_data_prop_description.rb +28 -0
  36. data/lib/omf-sfa/model/model_obj_prop_description.rb +49 -0
  37. data/lib/omf-sfa/model/ontology.rb +169 -0
  38. data/lib/omf-sfa/resource/README.md +24 -0
  39. data/lib/omf-sfa/resource/channel.rb +49 -0
  40. data/lib/omf-sfa/resource/comp_group.rb +41 -0
  41. data/lib/omf-sfa/resource/component_lease.rb +10 -0
  42. data/lib/omf-sfa/resource/constants.rb +24 -0
  43. data/lib/omf-sfa/resource/group_component.rb +35 -0
  44. data/lib/omf-sfa/resource/group_membership.rb +17 -0
  45. data/lib/omf-sfa/resource/gurn.rb +187 -0
  46. data/lib/omf-sfa/resource/interface.rb +78 -0
  47. data/lib/omf-sfa/resource/ip.rb +48 -0
  48. data/lib/omf-sfa/resource/link.rb +29 -0
  49. data/lib/omf-sfa/resource/node.rb +75 -0
  50. data/lib/omf-sfa/resource/oaccount.rb +94 -0
  51. data/lib/omf-sfa/resource/ocomponent.rb +134 -0
  52. data/lib/omf-sfa/resource/ogroup.rb +106 -0
  53. data/lib/omf-sfa/resource/olease.rb +61 -0
  54. data/lib/omf-sfa/resource/oproperty.rb +178 -0
  55. data/lib/omf-sfa/resource/oreference.rb +15 -0
  56. data/lib/omf-sfa/resource/oresource.rb +491 -0
  57. data/lib/omf-sfa/resource/project.rb +28 -0
  58. data/lib/omf-sfa/resource/project_membership.rb +13 -0
  59. data/lib/omf-sfa/resource/sfa_base.rb +544 -0
  60. data/lib/omf-sfa/resource/user.rb +25 -0
  61. data/lib/omf-sfa/resource.rb +20 -0
  62. data/lib/omf-sfa/util/create_sample_testbed.rb +68 -0
  63. data/lib/omf-sfa/util/load_from_sfa_xml.rb +65 -0
  64. data/lib/omf-sfa/version.rb +4 -0
  65. data/lib/omf_sfa.rb +5 -0
  66. data/omf_sfa.gemspec +46 -0
  67. data/owl/README +3 -0
  68. data/owl/ben-6509.rdf +1377 -0
  69. data/owl/ben-dell.rdf +586 -0
  70. data/owl/ben-dtn.rdf +1698 -0
  71. data/owl/ben.rdf +1335 -0
  72. data/owl/collections.owl +309 -0
  73. data/owl/compute.owl +1486 -0
  74. data/owl/domain.owl +444 -0
  75. data/owl/dtn.owl +1165 -0
  76. data/owl/ec2.owl +385 -0
  77. data/owl/ethernet.owl +466 -0
  78. data/owl/eucalyptus.owl +431 -0
  79. data/owl/id-mp-Request1.rdf +247 -0
  80. data/owl/itu-grid.owl +147 -0
  81. data/owl/kansei.owl +511 -0
  82. data/owl/layer.owl +645 -0
  83. data/owl/location.owl +117 -0
  84. data/owl/mass.rdf +608 -0
  85. data/owl/nlr.rdf +901 -0
  86. data/owl/orca.owl +181 -0
  87. data/owl/planetlab.owl +124 -0
  88. data/owl/protogeni.owl +467 -0
  89. data/owl/request-6509-2.rdf +150 -0
  90. data/owl/request-6509-3.rdf +158 -0
  91. data/owl/request-6509.rdf +199 -0
  92. data/owl/request.owl +222 -0
  93. data/owl/storage.owl +511 -0
  94. data/owl/topology.owl +608 -0
  95. data/schema/rspec-v3/ad-common.xsd +269 -0
  96. data/schema/rspec-v3/ad-reservation.rnc +12 -0
  97. data/schema/rspec-v3/ad-reservation.rng +28 -0
  98. data/schema/rspec-v3/ad-reservation.xsd +13 -0
  99. data/schema/rspec-v3/ad.rnc +151 -0
  100. data/schema/rspec-v3/ad.xsd +77 -0
  101. data/schema/rspec-v3/any-extension-schema.xsd +38 -0
  102. data/schema/rspec-v3/any-extension.rnc +30 -0
  103. data/schema/rspec-v3/common.rnc +185 -0
  104. data/schema/rspec-v3/manifest-common.xsd +244 -0
  105. data/schema/rspec-v3/manifest-request.xsd +95 -0
  106. data/schema/rspec-v3/manifest.rnc +62 -0
  107. data/schema/rspec-v3/manifest.xsd +34 -0
  108. data/schema/rspec-v3/request-common.xsd +219 -0
  109. data/schema/rspec-v3/request-reservation.rnc +12 -0
  110. data/schema/rspec-v3/request-reservation.xsd +13 -0
  111. data/schema/rspec-v3/request.rnc +118 -0
  112. data/schema/rspec-v3/request.xsd +94 -0
  113. data/share/assets/css/default.css +147 -0
  114. data/share/assets/css/rest_api.css +0 -0
  115. data/share/assets/network.html +28 -0
  116. data/share/assets/network.js +82 -0
  117. data/spec/am/am-rest/common.rb +29 -0
  118. data/spec/am/am-rest/resource_group_handler_XspecX.rb +97 -0
  119. data/spec/am/am-rest/resource_handler_spec.rb +204 -0
  120. data/spec/am/am-rpc/sfa_methods_spec.rb +150 -0
  121. data/spec/am/am_manager_spec.rb +307 -0
  122. data/spec/am/am_scheduler_spec.rb +57 -0
  123. data/spec/am/common.rb +24 -0
  124. data/spec/resource/common.rb +31 -0
  125. data/spec/resource/node_spec.rb +171 -0
  126. data/spec/resource/oaccount_spec.rb +92 -0
  127. data/spec/resource/ocomponent_spec.rb +225 -0
  128. data/spec/resource/ogroup_spec.rb +93 -0
  129. data/spec/resource/oresource_spec.rb +208 -0
  130. data/spec/resource_and_leases_spec.rb +377 -0
  131. data/test/OLD_FILES/assertion1.xml +117 -0
  132. data/test/OLD_FILES/greeter_spec.rb +15 -0
  133. data/test/OLD_FILES/mongo_test.rb +45 -0
  134. data/test/OLD_FILES/req-sfa-2.xml +6 -0
  135. data/test/OLD_FILES/req-sfa-g.xml +8 -0
  136. data/test/OLD_FILES/req-sfa-g2.xml +10 -0
  137. data/test/OLD_FILES/req-sfa-g3.xml +14 -0
  138. data/test/OLD_FILES/req-sfa.xml +6 -0
  139. data/test/OLD_FILES/req1.xml +22 -0
  140. data/test/OLD_FILES/req1b.xml +15 -0
  141. data/test/OLD_FILES/rspec-test.xml +1867 -0
  142. data/test/OLD_FILES/test.rb +67 -0
  143. data/test/OLD_FILES/test2.rb +32 -0
  144. data/test/am/am_manager_rspec_tests.rb +378 -0
  145. data/test/am/am_manager_tests.rb +518 -0
  146. data/test/am/am_scheduler_tests.rb +173 -0
  147. data/test/resource/olease_test.rb +74 -0
  148. data/test/sfa_requests/request.xml +5 -0
  149. data/test/sfa_requests/request1.xml +5 -0
  150. data/test/sfa_requests/request2.xml +5 -0
  151. data/test/sfa_requests/request3.xml +5 -0
  152. metadata +601 -0
@@ -0,0 +1,145 @@
1
+ require 'nokogiri'
2
+ require 'omf_base/lobject'
3
+
4
+ module OMF::SFA::AM
5
+ class Credential < OMF::Base::LObject
6
+
7
+
8
+ @config = OMF::Base::YAML.load('omf-sfa-am', :path => [File.dirname(__FILE__) + '/../../../etc/omf-sfa'])[:omf_sfa_am]
9
+
10
+ rpc = @config[:endpoints].select { |v| v[:type] == 'xmlrpc' }.first
11
+ trusted_roots = File.expand_path(rpc[:trusted_roots])
12
+ certs = Dir.entries(trusted_roots)
13
+ certs.delete("..")
14
+ certs.delete(".")
15
+ @@root_certs = certs.collect do |v|
16
+ v = File.join(trusted_roots, v)
17
+ end
18
+
19
+ @@xmlsec = 'xmlsec1'
20
+
21
+ # <?xml version="1.0"?>
22
+ # <signed-credential>
23
+ # <credential xml:id="ref0">
24
+ # <type>privilege</type>
25
+ # <serial>8</serial>
26
+ # <owner_gid>-----BEGIN CERTIFICATE-----...-----END CERTIFICATE-----</owner_gid>
27
+ # <owner_urn>urn:publicid:IDN+geni:gpo:gcf+user+alice</owner_urn>
28
+ # <target_gid>-----BEGIN CERTIFICATE-----...-----END CERTIFICATE-----</target_gid>
29
+ # <target_urn>urn:publicid:IDN+geni:gpo:gcf+slice+2c93-4a3:127.0.0.1%3A8000</target_urn>
30
+ # <uuid/>
31
+ # <expires>2012-02-01T03:03:33</expires>
32
+ # <privileges>
33
+ # <privilege><name>refresh</name><can_delegate>true</can_delegate></privilege>
34
+ # <privilege><name>embed</name><can_delegate>true</can_delegate></privilege>
35
+ # <privilege><name>bind</name><can_delegate>true</can_delegate></privilege>
36
+ # <privilege><name>control</name><can_delegate>true</can_delegate></privilege>
37
+ # <privilege><name>info</name><can_delegate>true</can_delegate></privilege>
38
+ # </privileges>
39
+ # </credential>
40
+ # <signatures>
41
+ # <Signature xmlns="http://www.w3.org/2000/09/xmldsig#" xml:id="Sig_ref0">
42
+ # ...
43
+ # </Signature>
44
+ # </signatures>
45
+ # </signed-credential>
46
+
47
+ def self.unmarshall(xml_text)
48
+ signer_urn = verify_signed_xml(xml_text)
49
+ cred = Nokogiri::XML.parse(xml_text)
50
+ unless cred.root.name == 'signed-credential'
51
+ raise "Expected 'signed-credential' but got '#{cred.root}'"
52
+ end
53
+ #puts @doc.to_xml
54
+ unless (type_el = cred.xpath('//credential/type')[0])
55
+ raise "Credential doesn't contain 'type' element"
56
+ end
57
+ self.verify_type(type_el.content)
58
+
59
+ #<owner_urn>urn:publicid:IDN+geni:gpo:gcf+user+alice</owner_urn>
60
+ self.new(cred, signer_urn)
61
+ end
62
+
63
+ # The xml _content_ (provided as string) should
64
+ # contain a _Signature_ tag.
65
+ #
66
+ # Returns urn of signer if signature is valid, otherwise throw an exception
67
+ #
68
+ def self.verify_signed_xml(content)
69
+ tf = nil
70
+ begin
71
+ #debug "Verifying: ", content
72
+ tf = Tempfile.open('omf-am-rpc')
73
+ tf << content
74
+ tf.close
75
+ trusted_pems = @@root_certs.map do |r|
76
+ "--trusted-pem #{r}"
77
+ end.join(' ')
78
+ cmd = "#{@@xmlsec} verify --enabled-key-data 'x509' #{trusted_pems} --print-xml-debug #{tf.path} 2> /dev/null"
79
+ #cmd = "#{@@xmlsec} verify --trusted-pem #{@@root_certs} --print-xml-debug #{tf.path} 2> /dev/null"
80
+ out = []
81
+ result = nil
82
+ IO.popen(cmd) do |so|
83
+ result = Nokogiri::XML.parse(so)
84
+ #debug result
85
+ end
86
+ unless (result.xpath('/VerificationContext')[0]['status'] == 'succeeded')
87
+ raise OMF::SFA::AM::InsufficientPrivilegesException.new("Error: Signature doesn't verify")#\n#{@signature.to_xml}"
88
+ end
89
+ # <Certificate>
90
+ # <SubjectName>/CN=geni//gpo//gcf.authority.sa</SubjectName>
91
+ # <IssuerName>/CN=geni//gpo//gcf.authority.sa</IssuerName>
92
+ # <SerialNumber>3</SerialNumber>
93
+ # </Certificate>
94
+ signer = result.xpath('//Certificate/SubjectName')[0].content
95
+ debug "Signer of cert is '#{signer}'"
96
+ return signer
97
+ ensure
98
+ tf.close! if tf
99
+ end
100
+ end
101
+
102
+ def self.verify_type(type)
103
+ raise "Implement 'verify_type' in '#{self}'"
104
+ end
105
+
106
+
107
+ attr_reader :owner_urn
108
+ attr_reader :target_urn
109
+ attr_reader :signer_urn
110
+ attr_reader :valid_until
111
+
112
+ def valid_at?(time = Time.now)
113
+ #debug ">>>> #{valid_until}"
114
+ time <= @valid_until
115
+ end
116
+
117
+ protected
118
+
119
+ # Create a credential described in +description_doc+
120
+ #
121
+ def initialize(description_doc, signer_urn)
122
+ unless el = description_doc.xpath('//credential/owner_urn')[0]
123
+ raise "Missing element 'owner_urn' in credential"
124
+ end
125
+ #URI:urn:publicid:IDN+topdomain:subdomain+user+pi
126
+ #@owner_urn = el.content[el.content.index('+')+1..el.content.length]
127
+ @owner_urn = el.content
128
+ unless el = description_doc.xpath('//credential/target_urn')[0]
129
+ raise "Missing element 'target_urn' in credential"
130
+ end
131
+ #URI:urn:publicid:IDN+topdomain:subdomain+slice+test
132
+ #@target_urn = el.content[el.content.index('+')+1..el.content.length]
133
+ @target_urn = el.content
134
+
135
+ unless el = description_doc.xpath('//credential/expires')[0]
136
+ raise "Missing element 'expires' in credential"
137
+ end
138
+ @valid_until = Time.parse(el.content)
139
+
140
+ @signer_urn = signer_urn
141
+ end
142
+
143
+
144
+ end # Credential
145
+ end # OMF::GENI::AM
@@ -0,0 +1,44 @@
1
+
2
+
3
+ require 'omf_base/lobject'
4
+
5
+ module OMF::SFA::AM
6
+
7
+ include OMF::Base
8
+
9
+ class InsufficientPrivilegesException < AMManagerException; end
10
+
11
+ # This class implements an authorizer which
12
+ # only allows actions which have been enabled in a permission
13
+ # hash.
14
+ #
15
+ class DefaultAuthorizer < LObject
16
+
17
+ [
18
+ # ACCOUNT
19
+ :can_create_account?, # ()
20
+ :can_view_account?, # (account)
21
+ :can_renew_account?, # (account, until)
22
+ :can_close_account?, # (account)
23
+ # RESOURCE
24
+ :can_create_resource?, # (resource_descr, type)
25
+ :can_view_resource?, # (resource)
26
+ :can_release_resource?, # (resource)
27
+ # LEASE
28
+ :can_view_lease?, # (lease)
29
+ :can_modify_lease?, # (lease)
30
+ :can_release_lease?, # (lease)
31
+ ].each do |m|
32
+ define_method(m) do |*args|
33
+ debug "Check permission '#{m}' (#{@permissions.inspect})"
34
+ unless @permissions[m]
35
+ raise InsufficientPrivilegesException.new
36
+ end
37
+ end
38
+ end
39
+
40
+ def initialize(permissions = {})
41
+ @permissions = permissions
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,76 @@
1
+ require 'omf-sfa/am/credential'
2
+
3
+ module OMF::SFA::AM
4
+
5
+ # Throws exception if credentials XML encoded in +cred_string_a+
6
+ # are *not* sufficient for _action_
7
+ #
8
+ # GENI API Credentials
9
+ #
10
+ # The privileges are the rights that are assigned to the owner
11
+ # of the credential on the target resource. Different slice
12
+ # authorities use different permission names, but they have
13
+ # similar semantic meaning. If and only if a privilege can
14
+ # be delegated, then that means the owner of the credential
15
+ # can delegate that permission to another entity.
16
+ # Currently, the only credentials used in the GENI API are
17
+ # slice credentials and user credentials. Privileges have not
18
+ # yet been agreed upon between the control frameworks.
19
+ # Currently, SFA assigns ['refresh', 'resolve', and 'info']
20
+ # rights to user credentials.
21
+ # Slice credentials have "slice" rights. ProtoGENI defaults
22
+ # to the "*" privilege which means that the owner has rights
23
+ # to all methods associated with that credential type
24
+ # (user or slice).
25
+ # See https://www.protogeni.net/trac/protogeni/wiki/ReferenceImplementationPrivileges
26
+ # for more information on ProtoGENI privileges.
27
+ #
28
+ class PrivilegeCredential < Credential
29
+ #attr_reader :privileges
30
+
31
+ def self.verify_type(type)
32
+ raise "Expected type 'privilege' but got '#{type}'" unless type == 'privilege'
33
+ end
34
+
35
+ def privilege?(pname)
36
+ @privileges.has_key?(pname)
37
+ end
38
+
39
+ def user_urn
40
+ owner_urn
41
+ end
42
+
43
+ def type
44
+ # urn:publicid:IDN+topdomain:subdomain+slice+test
45
+ target_urn.split('+')[2] # it should be one of "slice" or "user"
46
+ end
47
+
48
+
49
+ # Create a credential described in +description_doc+ .
50
+ #
51
+ def initialize(description_doc, signer_urn)
52
+ super
53
+ # @see http://groups.geni.net/geni/wiki/GeniApiCredentials
54
+ # <privileges>
55
+ # <privilege><name>refresh</name><can_delegate>true</can_delegate></privilege>
56
+ # <privilege><name>embed</name><can_delegate>true</can_delegate></privilege>
57
+ # <privilege><name>bind</name><can_delegate>true</can_delegate></privilege>
58
+ # <privilege><name>control</name><can_delegate>true</can_delegate></privilege>
59
+ # <privilege><name>info</name><can_delegate>true</can_delegate></privilege>
60
+ # </privileges>
61
+ unless el = description_doc.xpath('//credential/privileges')[0]
62
+ raise "Missing element 'privileges' in credential"
63
+ end
64
+ @privileges = {}
65
+ el.children.each do |pel|
66
+ p = {}
67
+ pel.children.each do |cel|
68
+ p[cel.name.to_sym] = cel.content
69
+ end
70
+ # example: @privileges={"refresh"=>{:can_delegate=>"true"}, "resolve"=>{:can_delegate=>"true"}, "info"=>{:can_delegate=>"true"}}
71
+ @privileges[p.delete(:name)] = p
72
+ end
73
+ end
74
+
75
+ end # PrivilegeCredential
76
+ end # OMF::SFA::AM
@@ -0,0 +1,37 @@
1
+
2
+ module OMF::GENI::AM
3
+ class Signature
4
+
5
+ # The xml _content_ (provided as string) should
6
+ # contain a _Signature_ tag.
7
+ #
8
+ # Returns a _Signature_ object if valid.
9
+ # Raises exception if not valid
10
+ #
11
+ def self.verify_xml_string(content)
12
+ tf = sig = nil
13
+ begin
14
+ tf = Tempfile.open('omf-am-rpc')
15
+ tf << content
16
+ tf.close
17
+ cmd = "#{@@xmlsec} verify --trusted-pem #{@@root_certs} --print-xml-debug #{tf.path} 2> /dev/null"
18
+ out = []
19
+ #IO.popen("#{cmd} 2>&1") do |so|
20
+ IO.popen(cmd) do |so|
21
+ sig = Nokogiri::XML.parse(so)
22
+ end
23
+ unless (sig.xpath('/VerificationContext')[0]['status'] == 'succeeded')
24
+ raise "Error: Signature doesn't verify\n#{sig.to_xml}"
25
+ end
26
+ ensure
27
+ tf.close! if tf
28
+ end
29
+ return Signature.new(sig)
30
+ end
31
+
32
+ def initialize(sig_doc)
33
+ @sig_doc = sig_doc
34
+ end
35
+
36
+ end # Signature
37
+ end # OMF::GENI::AM
@@ -0,0 +1,56 @@
1
+
2
+ require 'omf-sfa/am/credential'
3
+
4
+ module OMF::SFA::AM
5
+ class UserCredential < OMF::Base::LObject
6
+
7
+ include OMF::SFA::Resource
8
+
9
+ attr_reader :user_urn, :user_uuid
10
+
11
+ def self.unmarshall(cert_s)
12
+ cert = OpenSSL::X509::Certificate.new(cert_s)
13
+ #puts cert
14
+ unless OpenSSL::SSL::SSLContext::DEFAULT_CERT_STORE.verify(cert)
15
+ raise OMF::SFA::AM::InsufficientPrivilegesException.new("Non valid user cert")
16
+ end
17
+ self.new(cert)
18
+ end
19
+
20
+ def initialize(cert)
21
+ @cert = cert
22
+
23
+ @cert.extensions.each do |e|
24
+ if e.oid == 'subjectAltName'
25
+ #URI:urn:publicid:IDN+topdomain:subdomain+user+pi, URI:urn:uuid:759ae077-2fda-4d02-8921-ab0235a09920
26
+ e.value.split(',').each do |u|
27
+ u.slice!('URI:')
28
+ @user_urn = u.strip if u.start_with?('urn:publicid:IDN')
29
+ @user_uuid = u.match(/^urn:uuid:(.*)/)[1] if u.start_with?('urn:uuid')
30
+ end
31
+ #e.value.split('URI:urn:').each do |u|
32
+ # str = u.split('+')
33
+ # if str.include?('publicid:IDN')
34
+ # @user_urn = str[-3..-1].join('+').chomp(', ')
35
+ # end
36
+ # str = u.split(':')
37
+ # if str.include?('uuid')
38
+ # @user_uuid = str.last
39
+ # end
40
+ #end
41
+ end
42
+ end
43
+ end
44
+
45
+ def subject
46
+ @cert.subject
47
+ end
48
+
49
+ def valid_at?(time = Time.now)
50
+ debug "valid? #{@cert.not_before} < #{time} < #{@cert.not_after}"
51
+ time >= @cert.not_before && time <= @cert.not_after
52
+ end
53
+
54
+ end # UserCredential
55
+ end # OMF::SFA::AM
56
+
data/lib/omf-sfa/am.rb ADDED
@@ -0,0 +1,7 @@
1
+
2
+
3
+ require 'omf_sfa'
4
+
5
+ module OMF::SFA
6
+ module AM; end
7
+ end
@@ -0,0 +1,87 @@
1
+
2
+
3
+ # An +ModelDataPropertyDescription+ holds all the relevant information
4
+ # for describing properties of entities.
5
+ #
6
+
7
+ module OMF::SFA
8
+ module Model
9
+
10
+ class AbstractPropertyDescription < OMF::Base::LObject
11
+
12
+ @@name2inst = {}
13
+
14
+ def self.create_from_xml(cel)
15
+ about = cel.attribute_with_ns('about', RDF_NS)
16
+ name = xml_full_name(about.value, cel)
17
+ klass = @@name2inst[name] ||= self.new(name)
18
+ klass.parse(cel)
19
+ klass
20
+ end
21
+
22
+ def self.each(&block)
23
+ @@name2inst.values.each &block
24
+ end
25
+
26
+ attr_reader :name, :ns, :uri
27
+
28
+ def initialize(full_name)
29
+ @uri = full_name
30
+ @ns, @name = full_name.split('#')
31
+ super @name
32
+ end
33
+
34
+ def validate()
35
+ if @domain
36
+ @domain = validate_class_reference(@domain)
37
+ @domain.add_property(self)
38
+ else
39
+ #warn "No domain reference for property '#{@name}'"
40
+ end
41
+ end
42
+
43
+ # Return class description for +ref+
44
+ #
45
+ def validate_class_reference(ref)
46
+ unless ref.kind_of? ModelClassDescription
47
+ if ref
48
+ ref = ModelClassDescription[ref] || raise("Unknonw class '#{ref}'")
49
+ else
50
+ raise 'Empty class reference'
51
+ end
52
+ end
53
+ ref
54
+ end
55
+
56
+
57
+ def parse(cel)
58
+ cel.children.each do |el|
59
+ node_name = el.node_name
60
+ next if node_name == 'comment'
61
+
62
+ attr = el.attribute_with_ns('resource', RDF_NS)
63
+ res_name = attr ? xml_full_name(attr.value, el) : nil
64
+
65
+ parse_el(node_name, res_name, el)
66
+ end
67
+ end
68
+
69
+ def parse_el(node_name, res_name, el)
70
+ case node_name
71
+ when 'range'
72
+ @range = res_name # ModelClassDescription[res] || raise("Unknonw class '#{res}'")
73
+ when 'domain'
74
+ @domain = res_name
75
+ else
76
+ warn "Unknown eleement '#{node_name}' in '#{self.class.name}'"
77
+ end
78
+ end
79
+
80
+
81
+ def to_s
82
+ "#{@name} (#{self.class.name})"
83
+ end
84
+
85
+ end # AbstractPropDescription
86
+ end # Model
87
+ end # OMF::SFA
@@ -0,0 +1,145 @@
1
+
2
+ # An +MClass+ holds all the releevant information relevant to the
3
+ # specific model class in an overal model or schema.
4
+ #
5
+
6
+ module OMF::SFA
7
+ module Model
8
+
9
+ class ModelClassDescription < OMF::Base::LObject
10
+
11
+ @@name2inst = {}
12
+
13
+ def self.[](uri)
14
+ @@name2inst[uri]
15
+ end
16
+
17
+ def self.each(&block)
18
+ if block
19
+ @@name2inst.values.each &block
20
+ else
21
+ @@name2inst.values
22
+ end
23
+ end
24
+
25
+ def self.models()
26
+ @@name2inst.values
27
+ end
28
+
29
+ def self.create_from_xml(cel)
30
+ about = cel.attribute_with_ns('about', RDF_NS)
31
+ name = xml_full_name(about.value, cel)
32
+ klass = @@name2inst[name] ||= self.new(name)
33
+ klass.parse(cel)
34
+ klass
35
+ end
36
+
37
+
38
+ attr_reader :name, :ns, :uri
39
+
40
+ def initialize(full_name)
41
+ @uri = full_name
42
+ @ns, @name = full_name.split('#')
43
+ super @name
44
+ @properties = {}
45
+ @children = []
46
+ end
47
+
48
+ def add_property(prop_description)
49
+ name = prop_description.name
50
+ if p = @properties[name]
51
+ if p != prop_description
52
+ error "Trying to add additional property with smae name '#{name}'"
53
+ end
54
+ else
55
+ @properties[name] = prop_description
56
+ end
57
+ end
58
+
59
+
60
+ def parse(cel)
61
+ cel.children.each do |el|
62
+ node_name = el.node_name
63
+ next if node_name == 'comment'
64
+
65
+ case el.node_name
66
+ when 'subClassOf'
67
+ parse_super(el)
68
+ when 'disjointWith'
69
+ # <owl:disjointWith rdf:resource="#Item"/>
70
+ when 'label'
71
+ @label = el.content
72
+ else
73
+ warn "Unknown eleement '#{el.node_name}' in '#{self.class.name}'"
74
+ end
75
+ end
76
+ end
77
+
78
+ # TODO: Parsing of 'Restriction'
79
+ #
80
+ # <rdfs:subClassOf rdf:resource="#NetworkElement"/>
81
+ # <rdfs:subClassOf>
82
+ # <owl:Restriction>
83
+ # <owl:onProperty rdf:resource="#hasSwitchMatrix"/>
84
+ # <owl:someValuesFrom rdf:resource="#SwitchMatrix"/>
85
+ # </owl:Restriction>
86
+ # </rdfs:subClassOf>
87
+ #
88
+ def parse_super(el)
89
+ res = el.attribute_with_ns('resource', RDF_NS)
90
+ if res
91
+ if @superklass
92
+ warn "Don't really know how to handle multiple inheritence in '#{@name}'"
93
+ end
94
+ @superklass = xml_full_name(res.value, el)
95
+ end
96
+
97
+ end
98
+
99
+ def superklass
100
+ unless @superklass.kind_of? self.class
101
+ if klass = self.class[@superklass]
102
+ @superklass = klass
103
+ klass.add_child_class(self)
104
+ end
105
+ end
106
+ @superklass
107
+ end
108
+
109
+ def add_child_class(class_model)
110
+ @children << class_model
111
+ end
112
+
113
+ def describe(level = 0, max_level = 99)
114
+ if !@properties.empty? || level == 0
115
+ prefix = " " * level
116
+ puts "#{prefix}-------------------------"
117
+ puts "#{prefix}Class: #{name}"
118
+ describe_properties(prefix)
119
+ end
120
+ @children.each do |ch|
121
+ ch.describe level + 1, max_level
122
+ end
123
+ end
124
+
125
+ def describe_properties(prefix)
126
+ # if superklass.kind_of? self.class
127
+ # superklass.describe_properties
128
+ # end
129
+ @properties.each do |n, p|
130
+ mark = p.kind_of?(ModelDataPropertyDescription) ? '=' : '>'
131
+ puts "#{prefix} #{mark} #{n}"
132
+ end
133
+ end
134
+
135
+ def validate()
136
+ superklass
137
+ end
138
+
139
+ def to_s
140
+ "#{@name} (#{self.class.name}) - super: #{superklass || 'none'}"
141
+ end
142
+
143
+ end # ModelClassDescription
144
+ end # Model
145
+ end # OMF::SFA
@@ -0,0 +1,28 @@
1
+
2
+ require 'omf-sfa/model/abstract_prop_description'
3
+
4
+ # An +ModelDataPropertyDescription+ holds all the relevant information
5
+ # for describing properties of entities.
6
+ #
7
+
8
+ module OMF::SFA
9
+ module Model
10
+
11
+ class ModelDataPropertyDescription < AbstractPropertyDescription
12
+
13
+ # <owl:DatatypeProperty rdf:about="#numHop">
14
+ # <rdfs:domain rdf:resource="#NetworkTransportElement"/>
15
+ # <rdfs:range rdf:resource="&xsd;int"/>
16
+ # </owl:DatatypeProperty>
17
+ #
18
+ def parse_el(node_name, res_name, el)
19
+ case node_name
20
+ when 'XXX'
21
+ else
22
+ super
23
+ end
24
+ end
25
+
26
+ end # ModelClassDescription
27
+ end # Model
28
+ end # OMF::SFA
@@ -0,0 +1,49 @@
1
+
2
+ require 'omf-sfa/model/abstract_prop_description'
3
+
4
+ # An +ModelObjectPropertyDescription+ holds all the relevant information
5
+ # for describing relationship between entities.
6
+ #
7
+
8
+ module OMF::SFA
9
+ module Model
10
+
11
+ class ModelObjectPropertyDescription < AbstractPropertyDescription
12
+
13
+ @@types = {
14
+ 'http://www.w3.org/2002/07/owl#TransitiveProperty' => :transitive,
15
+ 'http://www.w3.org/2002/07/owl#FunctionalProperty' => :functional,
16
+ 'http://www.w3.org/2002/07/owl#InverseFunctionalProperty' => :inverse_functional,
17
+ 'http://www.w3.org/2002/07/owl#SymmetricProperty' => :symmetric,
18
+ 'http://www.w3.org/2002/07/owl#AsymmetricProperty' => :asymmetric,
19
+ 'http://www.w3.org/2002/07/owl#ReflexiveProperty' => :reflexive,
20
+ 'http://www.w3.org/2002/07/owl#IrreflexiveProperty' => :irreflexive
21
+ }
22
+
23
+
24
+ # <!-- http://geni-orca.renci.org/owl/topology.owl#connectedTo -->
25
+ #
26
+ # <owl:ObjectProperty rdf:about="#connectedTo">
27
+ # <rdf:type rdf:resource="&owl;TransitiveProperty"/>
28
+ # <rdfs:range rdf:resource="#NetworkElement"/>
29
+ # <rdfs:domain rdf:resource="#NetworkElement"/>
30
+ # <rdfs:subPropertyOf rdf:resource="&layer;feature"/>
31
+ # </owl:ObjectProperty>
32
+ #
33
+ def parse_el(node_name, res_name, el)
34
+ case node_name
35
+ when 'subPropertyOf'
36
+ @subPropertyOf = res_name
37
+ when 'type'
38
+ @type = @@types[res_name] || raise("Unknonw property type '#{res_name}'")
39
+ when 'inverseOf'
40
+ @inverseOf = res_name
41
+ else
42
+ super
43
+ end
44
+ end
45
+
46
+
47
+ end # ModelClassDescription
48
+ end # Model
49
+ end # OMF::SFA