From Rails to KrakenD proxy: config generation for your routes

require "action_dispatch/routing/inspector"

begin
  namespace :krakend do
    task :routes => :environment do

      inspector = ActionDispatch::Routing::RoutesInspector.new(Rails.application.routes.routes)
      formatter = CustomRoutesFormatter.new
      routes_filter = {}

      puts inspector.format(formatter, routes_filter)
    end
  end
end

class CustomRoutesFormatter < ActionDispatch::Routing::ConsoleFormatter::Expanded
  def section_title(title)
  end

  def section(routes)
    @buffer << draw_expanded_section(routes)
  end

  private

  def draw_expanded_section(routes)
    routes.map.each_with_index do |r, i|
      path = r[:path].gsub("(.:format)", "").gsub(/:([a-z_]*)/, "{\\1}")

      <<~MESSAGE.chomp
        {
          "endpoint": "#{path}",
          "method": "#{r[:verb]}",
          "querystring_params": ["*"],
          "extra_config": {},
          "output_encoding": "no-op",
          "concurrent_calls": 1,
          "headers_to_pass": ["*"],
          "backend": [
            {
              "url_pattern": "#{path}",
              "encoding": "no-op",
              "extra_config": {},
              "sd": "static",
              "host": [
                "http://rails-app"
              ],
              "disable_host_sanitize": true
            }
          ]
        },
      MESSAGE
    end
  end
end

This approach can help you easily build krakend.json for your rails application.

GopherCon 2019

Побывали на Российской ГоферКонфе 🙂

Было очень полезно и интересно, очень понравились доклады от Konrad Reiche(go generate: One File to Rule Them All) и Денис Исаев(Линтеры в Go: как их готовить).

http://gophercon-russia.ru

Golang Hints: Create MongoDB Object ID from String

Sometimes you may want to find something by the Object ID in your MongoDB and due to you URI or query string contains ID you should convert the string ID to Object ID.

Below is a code that converts string ID to Object ID:

 package main

import (
"go.mongodb.org/mongo-driver/bson/primitive"
"fmt"
)
func main() {
oid, err := primitive.ObjectIDFromHex(recordID)

fmt.Printf("%s %v", err, oid)

  // if err := collection.FindOne(ctx, bson.M{"_id": oid}).Decode(e); err != nil {
  // return nil, err
// }
}

Presenting Go-Up

Today I have started development of new package for Golang-developers – Go-Up. I made it because I have noticed that I should repeat some things with each new project on Golang, so the main purpose of Go-Up package is to simplify building of new Golang applications.

This is a beginning so I just want to share link to GitHub here – https://github.com/ildarusmanov/go-up

KrakenD config example

What is KrakenD?

KrakenD is your self-designed REST API Gateway that feeds from your existing data services (Your APIs, legacy, cloud, IoT…) Just define visually or in a configuration file the endpoints your applications will use and the KrakenD will fetch and transform the content at your will for you.

https://www.krakend.io

Configuration example(proxy for POST, GET requests):

{
  "version": 2,
  "extra_config": {
    "github_com/devopsfaith/krakend-gologging": {
      "level": "WARNING",
      "prefix": "[KRAKEND]",
      "syslog": false,
      "stdout": true
    },
    "github_com/devopsfaith/krakend-metrics": {
      "collection_time": "60s",
      "proxy_disabled": false,
      "router_disabled": false,
      "backend_disabled": false,
      "endpoint_disabled": false,
      "listen_address": ":8090"
    },
    "github_com/devopsfaith/krakend-cors": {
      "allow_origins": [ "*" ],
      "allow_methods": [ "POST", "GET", "PUT", "DELETE" ],
      "allow_headers": [
        "Origin",
        "Authorization",
        "Content-Type",
        "Accept",
        "X-Auth-Token"
      ],
      "expose_headers": [ "Content-Length" ],
      "max_age": "12h"
    }
  },
  "timeout": "3000ms",
  "cache_ttl": "300s",
  "output_encoding": "no-op",
  "name": "api-proxy",
  "port": 80,
  "endpoints": [
    {
      "endpoint": "/",
      "extra_config": {},
      "output_encoding": "no-op",
      "concurrent_calls": 1,
      "backend": [
        {
          "url_pattern": "/",
          "encoding": "no-op",
          "extra_config": {},
          "sd": "static",
          "host": [
            "http://some-landing"
          ],
          "disable_host_sanitize": false
        }
      ]
    },
    {
      "method": "GET",
      "endpoint": "/api/v1/endpoint}",
      "extra_config": {},
      "output_encoding": "no-op",
      "concurrent_calls": 1,
      "backend": [
        {
          "method": "POST",
          "url_pattern": "/api/v1/{endpoint}",
          "encoding": "no-op",
          "extra_config": {},
          "sd": "static",
          "host": [
            "http://backend-service-getter"
          ],
          "disable_host_sanitize": false
        }
      ]
    },
    {
      "method": "POST",
      "endpoint": "/api/v1/endpoint}",
      "extra_config": {},
      "output_encoding": "no-op",
      "concurrent_calls": 1,
      "backend": [
        {
          "method": "POST",
          "url_pattern": "/api/v1/{endpoint}",
          "encoding": "no-op",
          "extra_config": {},
          "sd": "static",
          "host": [
            "http://backend-service-poster"
          ],
          "disable_host_sanitize": false
        }
      ]
    },
}

go build failed with “errors.go:121:2: undefined: stack”

Problem that I have met today:

$ go build
# github.com/pkg/errors
../../../../pkg/mod/github.com/pkg/errors@v0.8.0/errors.go:121:2: undefined: stack

#How to solve

I don't know the source of the problem, but I have fixed it with upgrading errors package version in my go.mod file:

module github.com/project_package
require (
// ...
github.com/pkg/errors v0.8.1 // indirect
// ...
)

Golang 1.11.2: dep ensure failed

Problem:


$ dep ensure
panic: version queue is empty, should not happen
goroutine 1 [running]:
github.com/golang/dep/gps.(*solver).findValidVersion(0xc00021e000, 0xc00026ac80, 0xc0001e6440, 0x1, 0x1, 0x0, 0xc0001e6440)
/home/travis/gopath/src/github.com/golang/dep/gps/solver.go:915 +0x4ec
github.com/golang/dep/gps.(*solver).createVersionQueue(0xc00021e000, 0xc0003ab0c1, 0x14, 0x0, 0x0, 0xc0001e6440, 0x1, 0x1, 0x0, 0x0, ...)
/home/travis/gopath/src/github.com/golang/dep/gps/solver.go:902 +0x46e
github.com/golang/dep/gps.(*solver).solve(0xc00021e000, 0xa64e60, 0xc0000a8188, 0x7c72ab, 0x936c80, 0xc00003c060)
/home/travis/gopath/src/github.com/golang/dep/gps/solver.go:505 +0x611
github.com/golang/dep/gps.(*solver).Solve(0xc00021e000, 0xa64e60, 0xc0000a8188, 0xdfa9c8, 0xc00002c0dc, 0x1f, 0xc00019b5c0)
/home/travis/gopath/src/github.com/golang/dep/gps/solver.go:440 +0xc0
main.(*ensureCommand).runUpdate(0xc000185960, 0xc0000c6980, 0xc00019a860, 0x0, 0x0, 0xc0000f6090, 0xa68f00, 0xc0000afc80, 0xc00002c0c4, 0x37, ...)
/home/travis/gopath/src/github.com/golang/dep/cmd/dep/ensure.go:356 +0x1c0
main.(*ensureCommand).Run(0xc000185960, 0xc0000c6980, 0xc00019a860, 0x0, 0x0, 0x0, 0x0)
/home/travis/gopath/src/github.com/golang/dep/cmd/dep/ensure.go:216 +0x7d4
main.(*Config).Run(0xc0000af0e0, 0x0)
/home/travis/gopath/src/github.com/golang/dep/cmd/dep/main.go:212 +0x1070
main.main()
/home/travis/gopath/src/github.com/golang/dep/cmd/dep/main.go:84 +0x53d
The command "dep ensure -update" failed and exited with 2 during .

Solution:

Add to your Gopkg.toml this lines:


[[override]]
name = "gopkg.in/fsnotify.v1"
source = "gopkg.in/fsnotify/fsnotify.v1"

And try to start dep ensure again.

Golang и WOPI: превью документов через Office Online

Введение

Возникла у нас в компании проблема с превью документов, использовали мы для превью на портале всем известную тулзу от гугла. Но с ней были проблемы, у пользователя не всегда рендерился документ(видимо лимиты по количеству вызовов) и когда он рендерился, то бывало, что внешне превьюсильно отлиалосьот оригинала. Поэтому было решено разработать превью документов на нашем кор. портале с использованием уже имеющегося у нас Office Online.

Теория

По счастливому стечению обстоятельств для работы с документами в Office Online используется неплохо задокументированный протокол – WOPI (http://wopi.readthedocs.io/).

Что нам нужно реализовать для организации предпросмотра:

1) Нужно получить необходимые для обращения к Office Online данные:

– файл discovery.xml

– ссылка на файл /wopi/<fileId> и ссылка на действие офис онлайн из файла discovery.xml

– токен и время его жизни в виде таймстемпа в миллисекундах

2) Нужно написать реализацию метода CheckFileInfo, который будет возращать информацию о файле

3) Нужно написать реализацию метода GetFile, который будет возращать содержимое файла

Практика

Лучше слов расскажет код, шутка, на самом деле мне пока немного лень писать то, как это было реализовано 🙂

Но надеюсь, что и этот код сможет оказаться полезным.

https://github.com/ildarusmanov/msofficepreview