Build Status Code Climate Coverage Dependency Status Gem Version

ZMQ SOA Suite - Ruby Client & Service

This project is a ruby client&service implementation for ZMQ Service Suite.

Installation

Add this line to your application’s Gemfile:

gem 'zss'

And then execute:

$ bundle

Or install it yourself as:

$ gem install zss

NOTE:

You need to have 0MQ installed.

If you use MacOS just do

$ brew install zeromq

ZSS Client

“by require ‘zss’

default Client config

config = { frontend: ‘tcp://127.0.0.1:5560’, identity: ‘client’, timeout: 1000 # in ms }

it uses default configs

PongClient = ZSS::Client.new(:pong)

it uses configs

who can override just a single property

PongClient = ZSS::Client.new(:pong, config)

call Pong service on verb PING with “payload”

PongClient.ping(“payload”)

or

PongClient.call(“ping”, “payload”)

call Pong service on verb PING with “payload” and headers

PongClient.ping(“payload”, headers: { something: “data” })

or

PongClient.call(“ping”, “payload”, headers: { something: “data” })

call Pong service on verb PING with “payload”

PongClient.ping_pong(“payload”)

or

PongClient.call(“ping/pong”, “payload”)

Client errors

The client raises services errors using ZSS::Error class, with code, developer message and user message.

“by require ‘zss’

PongClient = ZSS::Client.new(:pong)

begin PongClient.ping(“payload”) rescue ZSS::Error => error puts “Status code: #errorerror.code” puts “User Message: #errorerror.user_message” puts “Developer Message: #errorerror.developer_message” end

ZSS Service

The ZSS Service is responsible for receiving ZSS Request and execute configured service handlers.

The main components are: * ZSS::Service.new(:sid, config)

This component responsible for receiving and routing ZSS requests. The first parameter is service identifier (sid), you can use either symbol or string. The configuration parameter will be used to pass heartbeat interval and broker backend address.

“by config = { backend: ‘tcp://127.0.0.1:7776’, # default: tcp://127.0.0.1:7776 heartbeat: 1000 # ms, default: 1s } service = ZSS::Service.new(:pong, config)

  • ZSS::Runner.run(:sid)

    This component is responsible to execute a ZSS::Service as daemon, when in background it redirects stdout to file and manages pid files. It uses daemon gem.

    $ bin/pong run

    or in background, where pidfile and logs are under /log

    $ bin/pong start/stop
  • ZSS::ServiceRegister

    This component is the glue entry point between Runner & Service.

NOTE: You can run services without using the runner and service register, they are just one way to run services, you can use your own. Using Runner and service registry all services are done on the same way and using shared infra.

Creating a new service step by step

Let’s create our first service sample, Ping-Pong, step by step. Note: For your next services you will be able to use Service Generation rake, but for now you learn what the rake does and why!

  • Create you service logic class, adding a pong_service.rb under /lib folder.

“by class PongService

# it print’s payload and headers on the console def ping(payload, headers) puts “Payload => #payload” puts “Headers => #headers”

return "PONG"

end

end

NOTE:* Headers parameter is optional!

  • Create the service registration, adding a service_register.rb under /lib folder.

“by module ZSS class ServiceRegister

def self.get_service
  config = Hashie::Mash.new(
    # this data should be received from a config file instead!
    backend: 'tcp://127.0.0.1:7776'
  )

  # create a service instance for sid :pong
  service = ZSS::Service.new(:pong, config)

  instance = PongService.new
  # register route ping for the service
  service.add_route(instance, :ping)

  service
end

end end

  • Hook your files by creating start.rb under /lib folder.

“by require ‘zss/service’

require_relative ‘service_register’ require_relative ‘pong_service’

  • Register LoggerFacade plugin/s

The ZSS library uses the LoggerFacade library to abstract logging info, so you should hook your plugins on start.rb.

“by

log level should be retrieved from a configuration file

plugin = LoggerFacade::Plugins::Console.new({ level: :debug }) LoggerFacade::Manager.use(plugin)

  • Create a binary file to run the service as daemon, such as bin/pong

“by

!/usr/bin/env ruby

require ‘rubygems’ unless defined?(Gem)

require ‘bundler/setup’ Bundler.require

$env = ENV[ZSS_ENV] || ‘development’

require ‘zss/runner’ require_relative ‘../lib/start’

Runner receives the identifier used for pid and log filename

ZSS::Runner.run(:pong)

NOTES: * ZSS_ENV: is used to identify the running environment

You running service example here

Returning errors

Every exception that is raised by the service is shield and result on a response with status code 500 with default user and developer messages.

The available errors dictionary is defined in error.json.

Raising different errors

“by raise Error[500]

or

raise Error.new

or

raise Error.new(500)

or with developer message override

raise Error.new(500, “this message should helpfull for developer!”)

“hen relevant errors should be raised be with developer messages!

New Error Types

New error types should be added to error.json using pull request.

ZSS Service Generation Rake

#TODO

rake zss:service sid (–airbrake)

It generates the service skeleton, adding several files into root directory: * sid - binary file named with sid * start.rb with console plugin attached (–airbrake will add Airbrake plugin also) * sid_service.rb * service_register.rb * config/application.yml * travis.yml * .rvmrc.sample * .rvmrc * .rspec * Gemfile * .gitignore

Contributing

  1. Fork it
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create new Pull Request

Bump versioning

We use bump gem to control gem versioning.

Bump Patch version

$ bump patch --tag

Bump Minor version

$ bump minor --tag

Bump Major version

$ bump major --tag

Running Specs

$ rspec

Coverage Report

$ open ./coverage/index.html