Skip to content

mikamiel/distributed-cfg-service-mk

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

11 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Сервис хранения конфигураций приложений (тестовое задание №2 - Distributed config)

Сервис реализован на Go. Общение клиентов с сервисом происходит по протоколу gRPC посредством protobuf-месаджей. Доступны следующие gRPC - вызовы:

Стандартные CRUD операции c конфигом:

  • CreateConfig(Config)
  • GetConfig(Service)
  • UpdateConfig(Config)
  • DeleteConfig(Service)

Доступ к архивным версиям конфига:

  • GetArchivedConfig(Timestamp)
  • ListConfigTimestamps(Service)

Управление подпиской клиентов на конфигурации (с целью запрета удаления конфигов на которые имеются подписки):

  • SubscribeClientApp(SubscriptionRequest)
  • UnSubscribeClientApp(SubscriptionRequest)
  • ListConfigSubscribers(Service)

Взаимодействие с сервисом

Хранимые конфигурации приложений представляют собой простые списки пар ключ-значение типа string.

Идентификация конфигов сервисом происходит по уникальному имени конфига.

Для удобства обновления клиентом конфигов, апдейт происходит в режиме слияния - т.е. чтобы изменить имеющийся конфиг, достаточно передать сервису только те пары ключ-значение у которых хотим поменять значения (либо же вообще новые пары добавляем), остальные ранее хранящиеся в конфиге пары останутся нетронутыми и будут неотьемлемой частью обновлённого конфига. Если же хочется вообще удалить какую-то прежнюю пару ключ-значение из конфига - достаточно присвоить ей значение пустой строки (!не пробела).

Пока конфиг не удалён - можно запросить любую его прежнюю версию из истории изменений (по таймстемпу): GetArchivedConfig(Timestamp). Список таких таймстемпов для конкретного конфига можно запросить с помощью ListConfigTimestamps(Service).

Конфиг невозможно удалить пока на него подписано хоть одно приложение. Приложение можно подписать/отписать соответствующими gRPC вызовами. Просмотреть список подписанных на конфиг приложений можно вызовом ListConfigSubscribers(Service).

Пример работы с сервисом:

package main

import (
	"context"
	"fmt"
	"log"
	"google.golang.org/grpc"
	pb "distributed-cfg-service-mk/proto"
)

func main() {

	conn, err := grpc.Dial("localhost:50051", grpc.WithInsecure())
	if err != nil {
		log.Fatalf("Did not connect: %v", err)
	}
	defer conn.Close()
	c := pb.NewDistributedCfgServiceMKClient(conn)

	service := "Service number one"

	params := []*pb.Parameter{
		{Key: "Tcp port", Value: "80"},
		{Key: "Memory limit", Value: "2gb"},
		{Key: "Root dir", Value: "/root"},
	}

	resp, err := c.CreateConfig(context.Background(), &pb.Config{Service: service, Parameters: params})
	if err != nil {
		fmt.Println(err)
	} else {
		fmt.Println(resp.Service)
		fmt.Println(resp.Timestamp.AsTime())
	}

	resp2, err := c.GetConfig(
		context.Background(),
		&pb.Service{Name: service},
	)
	if err != nil {
		fmt.Println(err)
	} else {
		fmt.Println(resp2.Service)
		fmt.Println(resp2.Parameters)
	}

В файле client/main.go можно посмотреть дополнительные примеры работы клиента с сервисом.

Код самого сервиса находится в файле server/main.go плюс protobuf-сгенерённые файлы в директории proto/*.pb.go.

С помощью приложенного докер-компоуз файла можно оперативно запустить тестовый экземпляр сервиса скомпонованного с БД и админкой для БД (соответствующий докер-имидж уже выложен на Докерхабе, если что), но докер-имидж можно собрать и из приложенного Dockerfile, он вполне рабочий.

Детали реализации

В академических целях исходим из предположения, что работа сервиса происходит в стерильных условиях, все друг-другу доверяют, поэтому все что касается безопасности - авторизаця, шифрование канала, валидация и т.п. исключаем (ну разве что немного валидации имеется чтобы не поломать логику хранилища).

Хранилище реализовано на БД PostgreSQL, через ORM-прослойку gorm. Версионирование конфига реализовано посредством поля updated_at с соотв таймстемпом в записях в таблицах БД.

Что не успел (увы, времени не хватило) реализовать

  • Самое главное - конечно же адекватное тестирование, будь то полноценные юнит тесты или хотя бы просто сравнение по набору got/want. То что сейчас есть, это просто несерьезно.
  • Лаконичная организация кода по файлам/функциям/методам.
  • Абстракция работы с хранилищем.
  • Совершенно точно имеются баги, тесты не успел, ну и вот...

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published