cpee-model-management 1.0.16 → 1.1.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: eb4c3a55fe08f20e52d1908aa0285f9783d8413a470bd0b034829569d7d39620
4
- data.tar.gz: f0eeae82d2bc796f2976375113f0bd8616cb59e9b4e95541f3175f9cbd6565d1
3
+ metadata.gz: 2407951bdeabf8fad81810a6c56b3ce1f8a28d17e583d6c32207424cdc11334a
4
+ data.tar.gz: 9286ff4e9aa86127c7ce19ab0bd0da71b596b6ef035a99b48bea5bc4e85f1383
5
5
  SHA512:
6
- metadata.gz: dce3271b164de9f31aa0aef4dde102501c448a93067f0259d787446facbc72a119e617f35c09a02778e20114a07acdb08a9b76493a297ac05130c7ad0b542786
7
- data.tar.gz: 1eac23abe60a8d110ff7e2b154502b4756629576b7d6c2a225360160ab31288fcb4d9e4ba58eed489261fcd21334fac96d9b18aab355e8b60d5b2374cfea5d60
6
+ metadata.gz: 27df5a985c2441e656cfaefcb72377bbf720d04fe21c49fb9866c2b1b42d314af515f3dba981e8afb4fb616d2a9cdc897af8fd048d7547f57cfac594cac0ab1c
7
+ data.tar.gz: 076150342b2320ac0103a245f2162e7c03450970c9d078cd1446b1f400996dea35f4350a0aacbeed696344d3d996337531e7a25daa42ab9e755b3c8687ef05cb
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = "cpee-model-management"
3
- s.version = "1.0.16"
3
+ s.version = "1.1.0"
4
4
  s.platform = Gem::Platform::RUBY
5
5
  s.license = "LGPL-3.0"
6
6
  s.summary = "(Lifecycle) manage your process models in a directory or git repo."
@@ -7,8 +7,6 @@ new = File.basename(new)
7
7
  `git -c user.name='Christine Ashcreek' -c user.email=dev@null.com -c push.default=simple add "#{new}" 2>/dev/null`
8
8
  `git -c user.name='Christine Ashcreek' -c user.email=dev@null.com -c push.default=simple add "#{new}.active" 2>/dev/null`
9
9
  `git -c user.name='Christine Ashcreek' -c user.email=dev@null.com -c push.default=simple add "#{new}.active-uuid" 2>/dev/null`
10
- `git -c user.name='Christine Ashcreek' -c user.email=dev@null.com -c push.default=simple add "#{new}.author" 2>/dev/null`
11
- `git -c user.name='Christine Ashcreek' -c user.email=dev@null.com -c push.default=simple add "#{new}.creator" 2>/dev/null`
12
- `git -c user.name='Christine Ashcreek' -c user.email=dev@null.com -c push.default=simple add "#{new}.stage" 2>/dev/null`
10
+ `git -c user.name='Christine Ashcreek' -c user.email=dev@null.com -c push.default=simple add "#{new}.attrs" 2>/dev/null`
13
11
  `git -c user.name='Christine Ashcreek' -c user.email=dev@null.com -c push.default=simple commit -m "#{author.gsub(/"/,"'")}"`
14
12
  `GIT_TERMINAL_PROMPT=0 git push` rescue nil
@@ -25,6 +25,7 @@ require 'fileutils'
25
25
  require 'pathname'
26
26
  require 'shellwords'
27
27
  require 'securerandom'
28
+ require 'cpee/redis'
28
29
 
29
30
  module CPEE
30
31
  module ModelManagement
@@ -38,10 +39,10 @@ module CPEE
38
39
  p2 = Pathname.new(File.dirname(new))
39
40
  told = File.basename(old)
40
41
  tnew = File.join(p1.relative_path_from(p1).to_s,File.basename(new))
41
- `git -c user.name='Christine Ashcreek' -c user.email=dev@null.com -c push.default=simple mv "#{told}" "#{tnew}" 2>/dev/null`
42
- `git -c user.name='Christine Ashcreek' -c user.email=dev@null.com -c push.default=simple rm -rf "#{told + '.active'}" 2>/dev/null`
43
- `git -c user.name='Christine Ashcreek' -c user.email=dev@null.com -c push.default=simple rm -rf "#{told + '.active-uuid'}" 2>/dev/null`
44
- `git -c user.name='Christine Ashcreek' -c user.email=dev@null.com -c push.default=simple mv "#{told + '.attrs'}" "#{tnew + '.author'}" 2>/dev/null`
42
+ `git -c user.name='Christine Ashcreek' -c user.email=dev@null.com -c push.default=simple mv "#{told}" "#{tnew}" 2>/dev/null`
43
+ `git -c user.name='Christine Ashcreek' -c user.email=dev@null.com -c push.default=simple rm -rf "#{told + '.active'}" 2>/dev/null`
44
+ `git -c user.name='Christine Ashcreek' -c user.email=dev@null.com -c push.default=simple rm -rf "#{told + '.active-uuid'}" 2>/dev/null`
45
+ `git -c user.name='Christine Ashcreek' -c user.email=dev@null.com -c push.default=simple mv "#{told + '.attrs'}" "#{tnew + '.attrs'}" 2>/dev/null`
45
46
  Dir.chdir(cdir)
46
47
  CPEE::ModelManagement::fs_mv(models,old,new) # fallback
47
48
  end
@@ -320,6 +321,19 @@ module CPEE
320
321
  attrs['author'] = author
321
322
  File.write(fname + '.attrs',JSON::pretty_generate(attrs))
322
323
 
324
+ Dir.glob(File.join(fname + '/*.xml')).each do |f|
325
+ XML::Smart::modify(f) do |doc|
326
+ doc.register_namespace 'p', 'http://cpee.org/ns/properties/2.0'
327
+ doc.find('/p:testset/p:attributes/p:design_dir').each do |ele|
328
+ ele.text = nname + '.dir'
329
+ end
330
+ attrs = doc.find('/p:testset/p:attributes/*').map do |e|
331
+ [e.qname.name,e.text]
332
+ end.to_h
333
+ end
334
+ File.write(f + '.attrs',JSON::pretty_generate(attrs))
335
+ end
336
+
323
337
  CPEE::ModelManagement::op author, 'mv', models, File.join(nname + '.dir'), File.join(name + '.dir')
324
338
  CPEE::ModelManagement::notify conns, 'rename', models, fnname, fname
325
339
  nil
@@ -345,7 +359,7 @@ module CPEE
345
359
  Dir.mkdir(fname)
346
360
  FileUtils.touch(File.join(fname,'.gitignore'))
347
361
 
348
- attrs = JSON::load File.open(fname + '.attrs')
362
+ attrs = {}
349
363
  attrs['creator'] = creator
350
364
  attrs['author'] = creator
351
365
  File.write(fname + '.attrs',JSON::pretty_generate(attrs))
@@ -494,6 +508,26 @@ module CPEE
494
508
  nil
495
509
  end
496
510
  end #}}}
511
+ class ShowUrl < Riddl::Implementation #{{{
512
+ def response
513
+ show = @a[0]
514
+ @status = 302
515
+ @headers << Riddl::Header.new('Location',show + @p.first.value)
516
+ end
517
+ end #}}}
518
+ class AbandonUrl < Riddl::Implementation #{{{
519
+ def response
520
+ aba = @p.first.value
521
+ res1 = Typhoeus.get(File.join(aba,'properties','state','/'))
522
+ if res1.success?
523
+ if res1.response_body == 'ready' || res1.response_body == 'stopped'
524
+ Typhoeus.put(File.join(aba,'properties','state','/'), headers: {'Content-Type' => 'application/x-www-form-urlencoded'}, body: "value=abandoned")
525
+ end
526
+ end
527
+ nil
528
+ end
529
+ end #}}}
530
+
497
531
  class MoveItem < Riddl::Implementation #{{{
498
532
  def response
499
533
  where = @a[0] == :main ? '' : Riddl::Protocols::Utils::unescape(@r[-2])
@@ -593,7 +627,17 @@ module CPEE
593
627
  end
594
628
  end #}}}
595
629
 
596
- class Active < Riddl::SSEImplementation #{{{
630
+ class ManagementSend < Riddl::SSEImplementation #{{{
631
+ def onopen
632
+ @conns = @a[0]
633
+ @conns << self
634
+ end
635
+ def onclose
636
+ @conns.delete(self)
637
+ end
638
+ end #}}}
639
+
640
+ class StatSend < Riddl::SSEImplementation #{{{
597
641
  def onopen
598
642
  @conns = @a[0]
599
643
  @conns << self
@@ -603,31 +647,234 @@ module CPEE
603
647
  end
604
648
  end #}}}
605
649
 
650
+ class StatReceive < Riddl::Implementation #{{{
651
+ def response
652
+ redis = @a[0]
653
+ receivers = @a[1]
654
+ topic = @p[1].value
655
+ event_name = @p[2].value
656
+ notification = JSON.parse(@p[3].value.read)
657
+
658
+ instancenr = notification['instance']
659
+ content = notification['content']
660
+ attr = content['attributes']
661
+ engine = notification['cpee']
662
+
663
+ prefix = File.join(engine,notification['instance-uuid'].to_s)
664
+
665
+ if topic == 'state' && event_name == 'change'
666
+ if %w{abandoned finished}.include?(content['state'])
667
+ parent = redis.get(File.join(prefix,'parent'))
668
+ oldstate = redis.get(File.join(prefix,'state'))
669
+ children = redis.lrange(File.join(prefix,'children'),0,-1)
670
+ redis.multi do |multi|
671
+ multi.decr(File.join(engine,oldstate)) rescue nil
672
+ multi.incr(File.join(engine,'total_' + content['state']))
673
+ multi.lrem(File.join(engine,'instances'),0,notification['instance-uuid'])
674
+ multi.del(File.join(prefix,'instance-url'))
675
+ multi.del(File.join(prefix,'author'))
676
+ multi.del(File.join(prefix,'path'))
677
+ multi.del(File.join(prefix,'name'))
678
+ multi.del(File.join(prefix,'state'))
679
+ multi.del(File.join(prefix,'cpu'))
680
+ multi.del(File.join(prefix,'mem'))
681
+ children.each do |child|
682
+ if parent
683
+ multi.set(File.join(engine,child,'parent'),parent)
684
+ else
685
+ multi.del(File.join(engine,child,'parent'))
686
+ end
687
+ end
688
+ multi.del(File.join(prefix,'children'))
689
+ multi.del(File.join(prefix,'parent'))
690
+ if parent
691
+ multi.lrem(File.join(engine,parent,'children'),0,notification['instance-uuid'].to_s)
692
+ end
693
+ end
694
+ elsif %w{ready}.include?(content['state'])
695
+ exi = true if redis.lrange(File.join(engine,'instances'),0,-1).include?(notification['instance-uuid'])
696
+ redis.multi do |multi|
697
+ unless exi
698
+ multi.incr(File.join(engine,'total_created'))
699
+ multi.incr(File.join(engine,'ready'))
700
+ multi.rpush(File.join(engine,'instances'),notification['instance-uuid'])
701
+ end
702
+ multi.set(File.join(prefix,'instance-url'),notification['instance-url'])
703
+ multi.set(File.join(prefix,'author'),attr['author'])
704
+ multi.set(File.join(prefix,'state'),content['state'])
705
+ multi.set(File.join(prefix,'path'),File.join(attr['design_dir'],attr['info']+'.xml')) unless attr['design_dir'].nil? || attr['info'].nil?
706
+ multi.set(File.join(prefix,'name'),attr['info'])
707
+ multi.set(File.join(prefix,'cpu'),0)
708
+ multi.set(File.join(prefix,'mem'),0)
709
+ end
710
+ elsif %w{stopping}.include?(content['state'])
711
+ redis.set(File.join(prefix,'state'),content['state'])
712
+ elsif %w{stopped}.include?(content['state'])
713
+ redis.multi do |multi|
714
+ multi.decr(File.join(engine,'running'))
715
+ multi.incr(File.join(engine,'stopped'))
716
+ multi.set(File.join(prefix,'state'),content['state'])
717
+ multi.set(File.join(prefix,'cpu'),0)
718
+ multi.set(File.join(prefix,'mem'),0)
719
+ end
720
+ elsif %w{running}.include?(content['state'])
721
+ oldstate = redis.get(File.join(prefix,'state'))
722
+ redis.multi do |multi|
723
+ multi.decr(File.join(engine,oldstate)) rescue nil
724
+ multi.incr(File.join(engine,'running'))
725
+ multi.set(File.join(prefix,'state'),content['state'])
726
+ end
727
+ end
728
+
729
+ url, author, path, name, state, parent = redis.mget(
730
+ File.join(prefix,'instance-url'),
731
+ File.join(prefix,'author'),
732
+ File.join(prefix,'path'),
733
+ File.join(prefix,'name'),
734
+ File.join(prefix,'state'),
735
+ File.join(prefix,'parent')
736
+ )
737
+ receivers.each do |conn|
738
+ conn.send JSON::generate(:topic => topic, :event => event_name, :engine => engine, :uuid => notification['instance-uuid'], :url => url, :author => author, :path => path.to_s, :name => name, :state => content['state'], :parent => parent.to_s)
739
+ end
740
+ elsif topic == 'task' && event_name == 'instantiation'
741
+ redis.multi do |multi|
742
+ multi.rpush(File.join(engine,notification['instance-uuid'],'children'),content['received']['CPEE-INSTANCE-UUID'])
743
+ multi.set(File.join(engine,content['received']['CPEE-INSTANCE-UUID'],'parent'),notification['instance-uuid'])
744
+ end
745
+ prefix = File.join(engine,content['received']['CPEE-INSTANCE-UUID'].to_s)
746
+ url, author, path, name, state, parent = redis.mget(
747
+ File.join(prefix,'instance-url'),
748
+ File.join(prefix,'author'),
749
+ File.join(prefix,'path'),
750
+ File.join(prefix,'name'),
751
+ File.join(prefix,'state'),
752
+ File.join(prefix,'parent')
753
+ )
754
+ receivers.each do |conn|
755
+ conn.send JSON::generate(:topic => 'state', :event => 'change', :engine => engine, :uuid => content['received']['CPEE-INSTANCE-UUID'], :url => url, :author => author, :path => path.to_s, :name => name, :state => state, :parent => parent.to_s)
756
+ end
757
+ elsif topic == 'status' && event_name == 'resource_utilization'
758
+ redis.multi do |multi|
759
+ multi.set(File.join(prefix,'cpu'),content['utime'] + content['stime'])
760
+ multi.set(File.join(prefix,'mem'),content['mib'])
761
+ end
762
+ receivers.each do |conn|
763
+ conn.send JSON::generate(:topic => topic, :event => event_name, :engine => engine, :uuid => notification['instance-uuid'], :cpu => content['utime'] + content['stime'], :mem => content['mib'])
764
+ end
765
+ elsif topic == 'node' && event_name == 'resource_utilization'
766
+ redis.multi do |multi|
767
+ multi.set(File.join(engine,'cpu_usage'),content['cpu_usage'])
768
+ multi.set(File.join(engine,'mem_free'),content['mem_free'])
769
+ multi.set(File.join(engine,'mem_total'),content['mem_total'])
770
+ multi.set(File.join(engine,'mem_available'),content['mem_available'])
771
+ end
772
+ receivers.each do |conn|
773
+ conn.send JSON::generate(:topic => topic, :event => event_name, :engine => engine, :cpu_usage => content['cpu_usage'], :mem_free => content['mem_free'], :mem_total => content['mem_total'], :mem_available => content['mem_available'])
774
+ end
775
+ end
776
+ end
777
+ end #}}}
778
+
779
+ class StatGet < Riddl::Implementation #{{{
780
+ def response
781
+ redis = @a[0]
782
+ engine = @p[0].value
783
+ res = redis.mapped_mget(
784
+ File.join(engine,'total_created'),
785
+ File.join(engine,'total_finished'),
786
+ File.join(engine,'total_abandoned'),
787
+ File.join(engine,'ready'),
788
+ File.join(engine,'stopped'),
789
+ File.join(engine,'running')
790
+ ).transform_keys{ |k| File.basename(k) }.transform_values(&:to_i)
791
+ Riddl::Parameter::Complex.new('stats','application/json',JSON::pretty_generate(res || []))
792
+ end
793
+ end #}}}
794
+ class InstancesGet < Riddl::Implementation #{{{
795
+ def response
796
+ redis = @a[0]
797
+ engine = @p[0].value
798
+ doc = XML::Smart.string('<instances/>')
799
+ redis.lrange(File.join(engine,'instances'),0,-1).each do |i|
800
+ prefix = File.join(engine,i.to_s)
801
+ url, author, path, name, state, cpu, mem, parent = redis.mget(
802
+ File.join(prefix,'instance-url'),
803
+ File.join(prefix,'author'),
804
+ File.join(prefix,'path'),
805
+ File.join(prefix,'name'),
806
+ File.join(prefix,'state'),
807
+ File.join(prefix,'cpu'),
808
+ File.join(prefix,'mem'),
809
+ File.join(prefix,'parent')
810
+ )
811
+ doc.root.add('instance', :uuid => i, :url => url, :author => author, :path => path, :name => name, :state => state, :cpu => cpu, :mem => mem, :parent => parent)
812
+ end
813
+ Riddl::Parameter::Complex.new('tree','text/xml',doc.to_s)
814
+ end
815
+ end #}}}
816
+ class InstanceGet < Riddl::Implementation #{{{
817
+ def response
818
+ redis = @a[0]
819
+ engine = @p[0].value
820
+ uuid = @r[-1]
821
+ prefix = File.join(engine,uuid.to_s)
822
+ url, author, path, name, state, cpu, mem, parent = redis.mget(
823
+ File.join(prefix,'instance-url'),
824
+ File.join(prefix,'author'),
825
+ File.join(prefix,'path'),
826
+ File.join(prefix,'name'),
827
+ File.join(prefix,'state'),
828
+ File.join(prefix,'cpu'),
829
+ File.join(prefix,'mem'),
830
+ File.join(prefix,'parent')
831
+ )
832
+ Riddl::Parameter::Complex.new('instance','application/json',JSON.generate(:uuid => uuid, :url => url, :author => author, :path => path, :name => name, :state => state, :cpu => cpu, :mem => mem, :parent => parent))
833
+ end
834
+ end #}}}
835
+
836
+
606
837
  def self::implementation(opts)
607
- opts[:connections] = []
838
+ opts[:management_receivers] = []
839
+ opts[:stat_receivers] = []
840
+
841
+ ### set redis_cmd to nil if you want to do global
842
+ ### at least redis_path or redis_url and redis_db have to be set if you do global
843
+ opts[:redis_path] ||= 'redis.sock' # use e.g. /tmp/redis.sock for global stuff. Look it up in your redis config
844
+ opts[:redis_db] ||= 0
845
+ ### optional redis stuff
846
+ opts[:redis_url] ||= nil
847
+ opts[:redis_cmd] ||= 'redis-server --port 0 --unixsocket #redis_path# --unixsocketperm 600 --pidfile #redis_pid# --dir #redis_db_dir# --dbfilename #redis_db_name# --databases 1 --save 900 1 --save 300 10 --save 60 10000 --rdbcompression yes --daemonize yes'
848
+ opts[:redis_pid] ||= 'redis.pid' # use e.g. /var/run/redis.pid if you do global. Look it up in your redis config
849
+ opts[:redis_db_name] ||= 'redis.rdb' # use e.g. /var/lib/redis.rdb for global stuff. Look it up in your redis config
850
+
851
+ CPEE::redis_connect opts, 'Server Main'
608
852
 
609
853
  Proc.new do
610
- on resource do
854
+ interface 'events' do
855
+ run StatReceive, opts[:redis], opts[:stat_receivers] if post 'event'
856
+ end
857
+ interface 'implementation' do
611
858
  run GetList, :main, opts[:views], opts[:models] if get 'stage'
612
859
  run GetListFull, opts[:views], opts[:models] if get 'full'
613
860
  run GetStages, opts[:themes] if get 'stages'
614
- run Create, :main, :cre, opts[:views], opts[:connections], opts[:templates], opts[:models] if post 'item'
615
- run Create, :main, :dup, opts[:views], opts[:connections], opts[:templates], opts[:models] if post 'duplicate'
616
- run CreateDir, opts[:connections], opts[:models] if post 'dir'
617
- run Active, opts[:connections] if sse
861
+ run Create, :main, :cre, opts[:views], opts[:management_receivers], opts[:templates], opts[:models] if post 'item'
862
+ run Create, :main, :dup, opts[:views], opts[:management_receivers], opts[:templates], opts[:models] if post 'duplicate'
863
+ run CreateDir, opts[:management_receivers], opts[:models] if post 'dir'
864
+ run ManagementSend, opts[:management_receivers] if sse
618
865
  on resource '[a-zA-Z0-9öäüÖÄÜ _-]+\.dir' do
619
866
  run GetList, :sub, opts[:views], opts[:models] if get 'stage'
620
- run Create, :sub, :cre, opts[:views], opts[:connections], opts[:templates], opts[:models] if post 'item'
621
- run Create, :sub, :dup, opts[:views], opts[:connections], opts[:templates], opts[:models] if post 'duplicate'
622
- run DeleteDir, opts[:connections], opts[:models] if delete
623
- run RenameDir, opts[:connections], opts[:models] if put 'name'
867
+ run Create, :sub, :cre, opts[:views], opts[:management_receivers], opts[:templates], opts[:models] if post 'item'
868
+ run Create, :sub, :dup, opts[:views], opts[:management_receivers], opts[:templates], opts[:models] if post 'duplicate'
869
+ run DeleteDir, opts[:management_receivers], opts[:models] if delete
870
+ run RenameDir, opts[:management_receivers], opts[:models] if put 'name'
624
871
  on resource '[a-zA-Z0-9öäüÖÄÜ _-]+\.xml' do
625
- run DeleteItem, :sub, opts[:connections], opts[:models] if delete
872
+ run DeleteItem, :sub, opts[:management_receivers], opts[:models] if delete
626
873
  run GetItem, :sub, opts[:models] if get
627
- run PutItem, :sub, opts[:connections], opts[:models] if put 'content'
628
- run RenameItem, :sub, opts[:connections], opts[:models] if put 'name'
629
- run MoveItem, :sub, opts[:connections], opts[:models] if put 'dirname'
630
- run ShiftItem, :sub, opts[:connections], opts[:themes], opts[:models] if put 'newstage'
874
+ run PutItem, :sub, opts[:management_receivers], opts[:models] if put 'content'
875
+ run RenameItem, :sub, opts[:management_receivers], opts[:models] if put 'name'
876
+ run MoveItem, :sub, opts[:management_receivers], opts[:models] if put 'dirname'
877
+ run ShiftItem, :sub, opts[:management_receivers], opts[:themes], opts[:models] if put 'newstage'
631
878
  on resource 'open' do
632
879
  run OpenItem, :sub, opts[:instantiate], opts[:cockpit], opts[:views], false, opts[:models] if get 'stage'
633
880
  end
@@ -637,12 +884,12 @@ module CPEE
637
884
  end
638
885
  end
639
886
  on resource '[a-zA-Z0-9öäüÖÄÜ _-]+\.xml' do
640
- run DeleteItem, :main, opts[:connections], opts[:models] if delete
887
+ run DeleteItem, :main, opts[:management_receivers], opts[:models] if delete
641
888
  run GetItem, :main, opts[:models] if get
642
- run PutItem, :main, opts[:connections], opts[:models] if put 'content'
643
- run RenameItem, :main, opts[:connections], opts[:models] if put 'name'
644
- run MoveItem, :main, opts[:connections], opts[:models] if put 'dirname'
645
- run ShiftItem, :main, opts[:connections], opts[:themes], opts[:models] if put 'newstage'
889
+ run PutItem, :main, opts[:management_receivers], opts[:models] if put 'content'
890
+ run RenameItem, :main, opts[:management_receivers], opts[:models] if put 'name'
891
+ run MoveItem, :main, opts[:management_receivers], opts[:models] if put 'dirname'
892
+ run ShiftItem, :main, opts[:management_receivers], opts[:themes], opts[:models] if put 'newstage'
646
893
  on resource 'open' do
647
894
  run OpenItem, :main, opts[:instantiate], opts[:cockpit], opts[:views], false, opts[:models] if get 'stage'
648
895
  end
@@ -650,6 +897,26 @@ module CPEE
650
897
  run OpenItem, :main, opts[:instantiate], opts[:cockpit], opts[:views], true, opts[:models] if get 'stage'
651
898
  end
652
899
  end
900
+ on resource 'dash' do
901
+ on resource 'show' do
902
+ run ShowUrl, opts[:show] if get 'url'
903
+ end
904
+ on resource 'abandon' do
905
+ run AbandonUrl if put 'url'
906
+ end
907
+ on resource 'events' do
908
+ run StatSend, opts[:stat_receivers] if sse
909
+ end
910
+ on resource 'instances' do
911
+ run InstancesGet, opts[:redis] if get 'engine'
912
+ on resource do
913
+ run InstanceGet, opts[:redis] if get 'engine'
914
+ end
915
+ end
916
+ on resource 'stats' do
917
+ run StatGet, opts[:redis] if get 'engine'
918
+ end
919
+ end
653
920
  end
654
921
  end
655
922
  end
@@ -0,0 +1,133 @@
1
+ <description xmlns="http://riddl.org/ns/description/1.0" xmlns:ann="http://riddl.org/ns/annotation/1.0" xmlns:xi="http://www.w3.org/2001/XInclude" datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
2
+ <message name="url">
3
+ <parameter name="url" type="string"/>
4
+ </message>
5
+ <message name="engine">
6
+ <parameter name="engine" type="string"/>
7
+ </message>
8
+ <message name="stats">
9
+ <parameter name="stats" mimetype="application/json"/>
10
+ </message>
11
+ <message name="tree">
12
+ <parameter name="tree" mimetype="text/xml"/>
13
+ </message>
14
+ <message name="instance">
15
+ <parameter name="instance" mimetype="application/json"/>
16
+ </message>
17
+ <message name="item">
18
+ <parameter name="stage" type="string">
19
+ <xi:include href="stages"/>
20
+ </parameter>
21
+ <parameter name="new" type="string">
22
+ <param name="pattern">[a-zA-Z0-9öäüÖÄÜ _-]+</param>
23
+ </parameter>
24
+ </message>
25
+ <message name="name">
26
+ <parameter name="new" type="string">
27
+ <param name="pattern">[a-zA-Z0-9öäüÖÄÜ _-]+</param>
28
+ </parameter>
29
+ </message>
30
+ <message name="dir">
31
+ <parameter name="dir" type="string">
32
+ <param name="pattern">([a-zA-Z0-9öäüÖÄÜ _-]+)|</param>
33
+ </parameter>
34
+ </message>
35
+ <message name="dirname">
36
+ <parameter name="dir" type="string">
37
+ <param name="pattern">([a-zA-Z0-9öäüÖÄÜ _-]+)\.dir|</param>
38
+ </parameter>
39
+ </message>
40
+ <message name="duplicate">
41
+ <parameter name="new" type="string">
42
+ <param name="pattern">[a-zA-Z0-9öäüÖÄÜ _-]+</param>
43
+ </parameter>
44
+ <parameter name="old" type="string">
45
+ <param name="pattern">[a-zA-Z0-9öäüÖÄÜ _-]+\.xml</param>
46
+ </parameter>
47
+ </message>
48
+ <message name="stages">
49
+ <parameter name="stages" type="string"/>
50
+ </message>
51
+ <message name="newstage">
52
+ <parameter name="stage" type="string">
53
+ <xi:include href="stages"/>
54
+ </parameter>
55
+ </message>
56
+ <message name="stage">
57
+ <optional>
58
+ <parameter name="stage" type="string">
59
+ <xi:include href="stages"/>
60
+ </parameter>
61
+ </optional>
62
+ </message>
63
+ <message name="full">
64
+ <parameter name="full" type="string"/>
65
+ <optional>
66
+ <parameter name="stage" type="string">
67
+ <xi:include href="stages"/>
68
+ </parameter>
69
+ </optional>
70
+ </message>
71
+ <message name="list">
72
+ <parameter name="list" mimetype="application/json"/>
73
+ </message>
74
+ <message name="content">
75
+ <parameter name="content" mimetype="application/xml"/>
76
+ </message>
77
+ <resource>
78
+ <post in="item"/>
79
+ <post in="dir"/>
80
+ <post in="duplicate"/>
81
+ <get in="stage" out="list"/>
82
+ <get in="full" out="list"/>
83
+ <get in="stages" out="list"/>
84
+ <sse/>
85
+ <resource relative="[a-zA-Z0-9&#xF6;&#xE4;&#xFC;&#xD6;&#xC4;&#xDC; _-]+\.dir">
86
+ <post in="item"/>
87
+ <post in="duplicate"/>
88
+ <get in="stage" out="list"/>
89
+ <delete/>
90
+ <put in="name"/> <!-- rename -->
91
+ <resource relative="[a-zA-Z0-9&#xF6;&#xE4;&#xFC;&#xD6;&#xC4;&#xDC; _-]+\.xml">
92
+ <get out='content'/>
93
+ <delete/>
94
+ <put in="content"/>
95
+ <put in="name"/> <!-- rename -->
96
+ <put in="dirname"/> <!-- move -->
97
+ <put in="newstage"/> <!-- shift -->
98
+ <resource relative="open"><get in="stage"/></resource>
99
+ <resource relative="open-new"><get in="stage"/></resource>
100
+ </resource>
101
+ </resource>
102
+ <resource relative="[a-zA-Z0-9&#xF6;&#xE4;&#xFC;&#xD6;&#xC4;&#xDC; _-]+\.xml">
103
+ <get out='content'/>
104
+ <delete/>
105
+ <put in="content"/>
106
+ <put in="name"/> <!-- rename -->
107
+ <put in="dirname"/> <!-- move -->
108
+ <put in="newstage"/> <!-- shift -->
109
+ <resource relative="open"><get in="stage"/></resource>
110
+ <resource relative="open-new"><get in="stage"/></resource>
111
+ </resource>
112
+ <resource relative="dash">
113
+ <resource relative="show">
114
+ <get in="url"/>
115
+ </resource>
116
+ <resource relative="abandon">
117
+ <put in="url"/>
118
+ </resource>
119
+ <resource relative="events">
120
+ <sse/>
121
+ </resource>
122
+ <resource relative="instances">
123
+ <get in="engine" out="tree"/>
124
+ <resource>
125
+ <get in="engine" out="instance"/>
126
+ </resource>
127
+ </resource>
128
+ <resource relative="stats">
129
+ <get in="engine" out="stats"/>
130
+ </resource>
131
+ </resource>
132
+ </resource>
133
+ </description>