coverage

release

Voca

Create&Manage Decidim instances on-the-fly, deploy all its ecosystem. Voca focuses on Decidim, released on APGL-3 open-source license and all the ecosystem around the platform. As Decidim is not a tool, but a framework for digital democratic participation, many tools gravitates around Decidim.

RPC private API for Decidim

This gem add internal functionalities to Decidim in order to be managed remotly. We do mostly:

  • Setup gruf to run a gRPC server
  • Implement the decidim.proto spec
  • Add a middleware two dynamically set config data.

RPC

From the .proto file, two files are generated, lib/decidim/voca/rpc/decidim_pb.rb and lib/decidim/voca/rpc/decidim_services_pb.rb. These files describe the skeletton of the input and response we need to comply.

In the controller Decidim::Voca::DecidimServiceController, we bind its method to these services and execute Commands for each methods. For example, a compile method is implemented this way:

    ## Compile assets.
    def compile_assets
        `bundle exec rails assets:precompile`
        ::Google::Protobuf::Empty.new
    end

When the code to resolves a RPC methods take more than 2 lines, we do a Command to isolate the code in one class. This is the case for most of the code. You can find the in the rpc directory.

Casting

As RPC is a generic way to build APIs, we have to translate constants in appropriate string for the application.

For example, SETTINGS_REGISTER_MODE_OPTION::SETTINGS_REGISTER_MODE_REGISTER_AND_LOGIN is actually just enable for the user_register_mode Decidim settings. To do so, we have an utility class Decidim::Voca::Rpc::EnumCaster.

Middleware

We get inspiration on this article to setup a middleware that retrieve config values from redis and then inject it into the code.

For every query, we do a small step of getting data from our Redis store, and inject the configuration object in Decidim. Like this:

 # ./lib/decidim/voca/middleware/dynamic_config_middleware.rb
    if config_data["currency_unit"].present?
        Decidim.currency_unit = config_data["currency_unit"]
    end

This is particularly usefull as it allows us to include Decidim configurations in our decidim.proto file, and set the redis value when needed.

# ./app/commands/decidim/voca/organization/update_locale_command.rb
global_configuration = locale_settings.select do |key| 
    "#{key}" == "currency_unit" || "#{key}" == "timezone"
end.delete_if { |_k, v| v.blank? }
unless global_configuration.empty?
    redis_client = Redis.new(
        url: ENV.fetch("REDIS_CONFIG_URL", "redis://127.0.0.1:6379/2"),
    );
    global_configuration.each do |key, value|
        # Update the Redis hash values
        redis_client.hset("config", "#{key}", "#{value}")
    end
    # Close the Redis connection
    redis_client.quit  
end

Repositories

repo info stable version
voca-system Install and manage decidim instances through a Dashboard v0.1.0
voca-tasks Gem embedded in our Decidim image. Manipulate and manage decidim instances. v0.1.0
voca-jps Jelastic Manifest to deploy Decidim images v0.1.0
voca-docker Build Decidim docker images for Voca v0.1.0
voca-protos RPC prototypes for voca v0.1.0

Decidim::Voca

This Gem allows configuring a Decidim instance with gRPC. This is a domain-specific gem, which is useful only if you host your own Voca system.

Readings before starting

Repository structure

Generated client

The client is generated with bundle exec rails update_voca_proto, and save the client and service in /lib/decidim/voca/rpc

RPC Decidim Service

The entry point for RPC Decidim Service is in /app/rpc/decidim/voca/decidim_service_controller.rb. This controller have a method per registered message, and will call some concerns in the /app/rpc/decidim/voca/rpc folder.

Updating commands

We use Rectify::Command in /app/commmands/decidim/voca for all update-related command.

Installation

Add this line to your application's Gemfile:

gem "decidim-voca"

And then execute:

bundle install

Development

We suppose you have docker installed in your environment.

docker-compose up -d
docker-compose run --rm app bash -c "cd $RAILS_ROOT && rails db:migrate"

Your development app with the gem is ready on http://localhost:3000

Run tests

test_app will create a spec/dummy app, and will run a local PostGres container. This command has to be done before executing tests.

bundle && bundle exec rails test_app

Once this command pass, execute:

bundle exec rspec spec

to run the unit tests.

Contributing

See Contributing.

License

See License.