hoth 0.3.4 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ log/
12
+ lib/bundler/man
13
+ pkg
14
+ rdoc
15
+ spec/reports
16
+ test/tmp
17
+ test/version_tmp
18
+ tmp
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format progress
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ # A sample Gemfile
2
+ source "http://rubygems.org"
3
+
4
+ gemspec
data/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2009 Dirk Breuer
1
+ Copyright (c) 2009-2012 Dirk Breuer
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
@@ -1,34 +1,34 @@
1
- = Hoth
1
+ # Hoth
2
2
 
3
3
  Creating a SOA requires a centralized location to define all services within the SOA. Furthermore you want to know where those services live.
4
4
 
5
- = How to use
5
+ # How to use
6
6
 
7
- == Install
7
+ ## Install
8
8
 
9
9
  gem install hoth
10
10
 
11
- == Define services and modules
11
+ ## Define services and modules
12
12
 
13
- === Service-Definition
13
+ ### Service-Definition
14
14
 
15
15
  This is how you define services:
16
16
 
17
17
  Hoth::Services.define do
18
-
18
+
19
19
  service :service_name do |first_param, second_param|
20
20
  returns :descriptive_name
21
21
  end
22
-
22
+
23
23
  end
24
24
 
25
25
  This definition describes a service with a name, some parameters and its return value. The naming of the parameters is just for your understanding and will never be used again, so be descriptive. Same goes for the return value. The only exception is, if you want to assure that a service returns nil you can write
26
-
26
+
27
27
  returns :nothing
28
-
28
+
29
29
  A service whith this return value will always return nil. You can also specify `:nil`, with the same result.
30
30
 
31
- === Module-Definition
31
+ ### Module-Definition
32
32
 
33
33
  After defining all you services, you need to specify in which modules they live. Each module can be seen as a set of implemented services. Each module can have one or more endpoints. Here is how you define these modules with its endpoints and services:
34
34
 
@@ -43,11 +43,6 @@ After defining all you services, you need to specify in which modules they live.
43
43
  transport :http
44
44
  end
45
45
 
46
- endpoint :bert do
47
- host 'localhost'
48
- port 9999
49
- transport :bert
50
- end
51
46
  end
52
47
 
53
48
  env :production do
@@ -57,38 +52,43 @@ After defining all you services, you need to specify in which modules they live.
57
52
  transport :http
58
53
  end
59
54
 
60
- endpoint :bert do
55
+ endpoint :beanstalk do
61
56
  host '192.168.1.15'
62
- port 9999
63
- transport :bert
57
+ port 11300
58
+ transport :beanstalkd
64
59
  end
65
60
  end
66
-
61
+
67
62
  add_service :first_service
68
- add_service :second_service, :via => :bert
63
+ add_service :second_service, :via => :beanstalk
69
64
  end
70
-
65
+
71
66
  end
72
67
 
73
68
 
74
69
  As you can see, it is possible to define different endpoints for different environments. Each endpoint has a host, a port and a transport-type. After defining your endpoints you can add your previously defined services to the module and define which endpoint they should use. If you do not specify an endpoint the :default endpoint will be used.
75
70
 
76
- == Integrate in your project
71
+ ## Integrate in your project
77
72
 
78
73
  Just execute current code (in rails you can add this line to an initializer):
79
-
74
+
80
75
  Hoth.init!
81
-
76
+
82
77
  By default, Hoth looks for the files service_definition and module_definition in the config-Directory (`./config`). If you need to load these files from another place, just set `Hoth.config_path` to your needs.
83
-
84
- == Note on Patches/Pull Requests
85
-
86
- * Fork the project.
87
- * Make your feature addition or bug fix.
88
- * Add tests for it. This is important so I don't break it in a future version unintentionally.
89
- * Commit, do not mess with rakefile, version, or history. (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
90
- * Send me a pull request. Bonus points for topic branches.
91
-
92
- == Copyright
78
+
79
+ ## Todo
80
+
81
+ * Make the rack provider independent from one specific transport.
82
+ * Make the bodies of the `rack_provider` return an object which responds to each in order not break on Ruby 1.9.
83
+
84
+ ## Note on Patches/Pull Requests
85
+
86
+ * Fork the project.
87
+ * Make your feature addition or bug fix.
88
+ * Add tests for it. This is important so I don't break it in a future version unintentionally.
89
+ * Commit, do not mess with rakefile, version, or history. (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
90
+ * Send me a pull request. Bonus points for topic branches.
91
+
92
+ ## Copyright
93
93
 
94
94
  Copyright (c) 2009-2010 Dirk Breuer. See LICENSE for details.
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env rake
2
+
3
+ require 'bundler/setup'
4
+ require 'bundler/gem_tasks'
5
+ require 'rspec/core/rake_task'
6
+ require 'hoth/version'
7
+ require 'yard'
8
+
9
+ RSpec::Core::RakeTask.new(:spec)
10
+
11
+ task :default => :spec
12
+
13
+ YARD::Rake::YardocTask.new do |t|
14
+ t.options += ['--title', "Hoth #{Hoth::VERSION} Documentation"]
15
+ end
@@ -0,0 +1,60 @@
1
+ require 'active_support'
2
+
3
+ class StatisticsObject
4
+ attr_accessor :id, :owner_id, :statistic_type, :timestamp, :group_condition
5
+
6
+ def initialize(attributes)
7
+ @id = attributes[:id]
8
+ @owner_id = attributes[:owner_id]
9
+ @statistic_type = attributes[:statistic_type]
10
+ @timestamp = attributes[:timestamp]
11
+ @group_condition = attributes[:group_condition]
12
+ end
13
+
14
+ def self.json_create(hash)
15
+ new(hash.symbolize_keys)
16
+ end
17
+ end
18
+
19
+ class Event
20
+ attr_accessor :name, :count
21
+
22
+ def initialize(attributes)
23
+ @name = attributes[:name]
24
+ @count = attributes[:count]
25
+ end
26
+
27
+ def self.json_create(hash)
28
+ new(hash.symbolize_keys)
29
+ end
30
+ end
31
+
32
+ class StatisticData
33
+ attr_accessor :events, :original_id
34
+
35
+ def initialize(attributes)
36
+ @events = attributes[:events]
37
+ @original_id = attributes[:original_id]
38
+ end
39
+
40
+ def self.json_create(hash)
41
+ new(hash.symbolize_keys)
42
+ end
43
+ end
44
+
45
+ class Account
46
+ attr_accessor :firstname, :lastname, :contract, :company
47
+
48
+ def initialize(attributes)
49
+ @firstname = attributes[:firstname]
50
+ @lastname = attributes[:lastname]
51
+ @contract = attributes[:contract]
52
+ @company = attributes[:company]
53
+ @contract
54
+ end
55
+
56
+ def to_serialize
57
+ [:firstname, :lastname, :contract, :company]
58
+ end
59
+
60
+ end
@@ -0,0 +1,32 @@
1
+ Hoth::Modules.define do
2
+ service_module :statistics_module do
3
+ env :development do
4
+ endpoint :default do
5
+ host '127.0.0.1'
6
+ port 443
7
+ transport :json_via_https
8
+ end
9
+ end
10
+
11
+ add_service :increment_statistics
12
+ add_service :statistic_of_cars
13
+ end
14
+
15
+ service_module :accounts_module do
16
+ env :development do
17
+ endpoint :default do
18
+ host 'localhost'
19
+ port 3000
20
+ transport :http
21
+ end
22
+
23
+ endpoint :beanstalk do
24
+ host 'localhost'
25
+ port 11300
26
+ transport :beanstalkd
27
+ end
28
+ end
29
+
30
+ add_service :create_account, :via => :beanstalk
31
+ end
32
+ end
@@ -0,0 +1,15 @@
1
+ Hoth::Services.define do
2
+
3
+ service :increment_statistics do |statistic_objects, event|
4
+ returns :nothing
5
+ end
6
+
7
+ service :statistic_of_cars do |ids|
8
+ returns :statistic_datas
9
+ end
10
+
11
+ service :create_account do |account|
12
+ returns :account_ids
13
+ end
14
+
15
+ end
@@ -0,0 +1,37 @@
1
+ $:.unshift(File.join("..", "lib"))
2
+
3
+ require 'rubygems'
4
+
5
+ require 'rack'
6
+ require 'hoth'
7
+ require 'hoth/providers/rack_provider'
8
+ require 'business_objects'
9
+
10
+ Hoth.init!
11
+
12
+ class IncrementStatisticsImpl
13
+ def self.execute(statistic_objects, event)
14
+ puts "** EXECUTING IncrementStatisticsImpl"
15
+ puts " statistic_objects: #{statistic_objects.inspect}"
16
+ puts " events: #{event.inspect}"
17
+ end
18
+ end
19
+
20
+ class StatisticOfCarsImpl
21
+ def self.execute(ids)
22
+ puts "** EXECUTING StatisticOfCarsImpl"
23
+ puts " ids: #{ids.inspect}"
24
+
25
+ return ids.inject([]) do |data, id|
26
+ data << StatisticData.new(
27
+ :events => [Event.new(:name => "viewed", :count => rand(666))],
28
+ :original_id => id
29
+ )
30
+ end
31
+ end
32
+ end
33
+
34
+ app = lambda {|env| [200, {'Content-Type' => 'application/json'}, ["body"]]}
35
+
36
+ rack_thread = Thread.new { run Hoth::Providers::RackProvider.new(app) }
37
+ rack_thread.join
@@ -0,0 +1,32 @@
1
+ $:.unshift(File.join("..", "lib"))
2
+
3
+ require 'rubygems'
4
+
5
+ require 'hoth'
6
+ require 'business_objects'
7
+
8
+ Hoth.init!
9
+
10
+ statistic_object = StatisticsObject.new(
11
+ :id => 23,
12
+ :owner_id => 42,
13
+ :statistic_type => "Car",
14
+ :timestamp => Time.now,
15
+ :group_condition => nil
16
+ )
17
+
18
+ event = Event.new(:name => "viewed", :count => 2)
19
+
20
+ puts "call increment_statistics"
21
+ Hoth::Services.increment_statistics([statistic_object], event)
22
+
23
+ puts Hoth::Services.statistic_of_cars([23, 42, 303, 101]).inspect
24
+
25
+ # account = Account.new(
26
+ # :firstname => "Dirk",
27
+ # :lastname => "Breuer",
28
+ # :contract => "Platinum",
29
+ # :company => "Galaxy Cats"
30
+ # )
31
+ #
32
+ # puts "Account ID: #{Hoth::Services.create_account(account)}"
@@ -0,0 +1,17 @@
1
+ # Very basic and simple example of using Hoth
2
+
3
+ This is a very simple example of using Hoth. It shows you how to define a module (math)
4
+ and a service (addition) using a very basic RackProvider. It also demonstrates how Hoth
5
+ choose if it should invoke the service by a remote call or locally (this works by
6
+ looking for a local implementation of the service, see `simple_client.rb`).
7
+
8
+ To run this example you need to start the RackProvider first:
9
+
10
+ cd example/simple
11
+ rackup simple_provider.ru
12
+
13
+ Next: Run the client:
14
+
15
+ ruby simple_client.rb
16
+
17
+ Have fun!
@@ -0,0 +1,13 @@
1
+ Hoth::Modules.define do
2
+ service_module :math_module do
3
+ env :development do
4
+ endpoint :default do
5
+ host 'localhost'
6
+ port 9292
7
+ transport :json_via_http
8
+ end
9
+ end
10
+
11
+ add_service :addition
12
+ end
13
+ end
@@ -0,0 +1,5 @@
1
+ Hoth::Services.define do
2
+ service :addition do |a, b|
3
+ returns :fixnum
4
+ end
5
+ end
@@ -0,0 +1,27 @@
1
+ # the client requires you to have a running provider (see simple_provider.ru)
2
+
3
+ $:.unshift(File.join("..", "..", "lib"))
4
+
5
+ require 'rubygems'
6
+
7
+ require 'hoth'
8
+
9
+ # first we initialize Hoth (this will load the configuration as well)
10
+ Hoth.init!
11
+
12
+ # let's call the "addition" service and show the result!
13
+ puts Hoth::Services.addition(40, 2)
14
+ # => 42
15
+
16
+ # Next, we will implement addition locally...
17
+ class AdditionImpl
18
+ def self.execute(a, b)
19
+ puts "I'm local!"
20
+ return a + b
21
+ end
22
+ end
23
+
24
+ # And call the service locally!
25
+ puts Hoth::Services.addition(1, 2)
26
+ # => I'm local!
27
+ # => 3
@@ -0,0 +1,30 @@
1
+ # to run this provider, use: rackup simple_provider.ru
2
+
3
+ $:.unshift(File.join("..", "..", "lib"))
4
+
5
+ require 'rubygems'
6
+
7
+ require 'rack'
8
+ require 'hoth'
9
+ require 'hoth/providers/rack_provider'
10
+
11
+ require "logger"
12
+
13
+ # Initialize Hoth, load service and module definitions
14
+ Hoth.init!
15
+
16
+ # Example, how you can specify your own log provider
17
+ Hoth::Logger.log_provider = Logger.new(STDOUT)
18
+ Hoth::Logger.log_provider.level = Logger::WARN
19
+
20
+ # To implement the service "addition", we need to provide AdditionImpl.execute
21
+ class AdditionImpl
22
+ def self.execute(a, b)
23
+ return a + b
24
+ end
25
+ end
26
+
27
+ # here we go!
28
+ app = lambda {|env| [200, {'Content-Type' => 'application/json'}, ["body"]]}
29
+ run Hoth::Providers::RackProvider.new(app)
30
+