Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .env
Original file line number Diff line number Diff line change
@@ -1 +1 @@
DICT_VERSION=0.0.22
DICT_VERSION=0.0.23
28 changes: 26 additions & 2 deletions cmd/dictionary-service/configuration.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,41 @@ import (

func makeConfigurationEndpoints(r *mux.Router, configurationService configuration.Service) {

// swagger:route PUT /api/config/{key}/value/{from} updateConfigValue
//
// Create new config value in time for existing key
// Responses:
// 200:
// 400: RestError
r.Methods("PUT", "OPTIONS").Path("/api/config/{key}/value/{from}").Handler(http.NewServer(
rest.MakeUpdateValueInTimeEndpoint(configurationService),
rest.DecodeUpdateValueInTimeRequest,
common.EncodeWithStatus(200),
))

// swagger:route POST /api/config/{key}/value addNewConfigEntry
//
// Create new config value in time for existing key
// Responses:
// 201:
// 400: RestError
r.Methods("POST", "OPTIONS").Path("/api/config/{key}/value").Handler(http.NewServer(
rest.MakeAddNewConfigurationValueEndpoint(configurationService),
rest.DecodeAddNewConfigurationValueRequest,
common.EncodeWithStatus(201),
))

// swagger:route DELETE /api/config deleteConfigurationEntry
//
// Save new config value
// Delete config value by key and date
// Responses:
// 204:
// 400: RestError
r.Methods("DELETE", "OPTIONS").Path("/api/config").Handler(http.NewServer(
rest.MakeDeleteConfigurationValueEndpoint(configurationService),
rest.DecodeDeleteConfigurationRequest,
common.EncodeWithStatus(204),
))
)) // todo: should be changed to DELETE /api/config/{key}/value/{from}

// swagger:route PUT /api/config updateConfiguration
//
Expand Down
26 changes: 26 additions & 0 deletions configuration/repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ type Repository interface {
LoadValues(tenant, key string) ([]Configuration, error)
Update(configuration *Configuration) error
DeleteValue(tenant, key string, dateFrom time.Time) error
LoadFirst(key, tenant string) (*Configuration, error)
LoadById(key, tenant string, from time.Time) (Configuration, error)
}

type configurationRepository struct {
Expand All @@ -38,6 +40,30 @@ func (c *configurationRepository) LoadForDay(key, tenant string, day time.Time)
return config, err
}

func (c *configurationRepository) LoadFirst(key, tenant string) (*Configuration, error) {

config := &Configuration{}
_, err := c.db.Query(config, `select * from dictionary.configuration where key = ? and tenant = ? order by date_from limit 1`, key, tenant)

return config, err

}

func (c *configurationRepository) LoadById(key, tenant string, from time.Time) (Configuration, error) {

var result = Configuration{
Key: key,
Tenant: tenant,
DateFrom: from,
}

err := c.db.Model(&result).
WherePK().
Select()

return result, err
}

func (c *configurationRepository) Load(key, tenant string, from, to time.Time) ([]Configuration, error) {

var result []Configuration
Expand Down
72 changes: 72 additions & 0 deletions configuration/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"database/sql"
"dictionaries-service/tenant"
"dictionaries-service/util"
"fmt"
slog "github.com/go-eden/slf4go"
"time"
Expand All @@ -27,6 +28,9 @@ type Service interface {
LoadValues(ctx context.Context, key string) ([]Configuration, error)
Update(configuration *Configuration) error
DeleteValue(ctx context.Context, key string, dateFrom time.Time) error
AddNewValueInTime(ctx context.Context, key string, value *string, dateFrom, dateTo time.Time) error
UpdateValueInTime(ctx context.Context, key string, dateFrom time.Time, newValue *string) error
LoadEntry(ctx context.Context, key string) (*Configuration, error)
}

func (c *service) LoadForDay(key, tenant string, day time.Time) (*Configuration, error) {
Expand Down Expand Up @@ -81,6 +85,74 @@ func (c *service) Update(configuration *Configuration) error {
return c.repository.Update(configuration)
}

func (c *service) AddNewValueInTime(ctx context.Context, key string, value *string, dateFrom, dateTo time.Time) error {

t, ok := tenant.FromContext(ctx)
if !ok {
return fmt.Errorf("can't read tenant from context")
}

origin, err := c.repository.LoadFirst(key, t.Name)

if err != nil {
slog.Warnf("can't read config entry for key = %s, %v", key, err)
return fmt.Errorf("there is no config entry for given key = %s", key)
}

err = c.repository.Save(&Configuration{
Key: key,
Tenant: t.Name,
Type: origin.Type,
Name: origin.Name,
Value: util.PointerToSqlNullString(value),
DateFrom: dateFrom,
DateTo: dateTo,
})
if err != nil {
return err
}

return nil
}

func (c *service) LoadEntry(ctx context.Context, key string) (*Configuration, error) {

t, ok := tenant.FromContext(ctx)
if !ok {
return nil, fmt.Errorf("can't read tenant from context")
}

return c.repository.LoadFirst(key, t.Name)
}

func (c *service) UpdateValueInTime(ctx context.Context, key string, dateFrom time.Time, newValue *string) error {

t, ok := tenant.FromContext(ctx)
if !ok {
return fmt.Errorf("can't read tenant from context")
}

origin, err := c.repository.LoadById(key, t.Name, dateFrom)

if err != nil {
slog.Warnf("can't read config entry for key = %s, and date_from = %s, %v", key, dateFrom, err)
return fmt.Errorf("there is no config entry for given key = %s and date_from = %s", key, dateFrom)
}

origin.Value = util.PointerToSqlNullString(newValue)

err = c.repository.Update(&origin)
if err != nil {
slog.Warnf("can't update config value for key = %s, and date_from = %s, %v", key, dateFrom, err)
return err
}
return nil
}

func (c *service) UpdateDateTo(key string, dateFrom, newDateTo time.Time) {

}

func (c *service) NewConfigValue(key, tenant, configType, name, value string) error {
conf := &Configuration{
Key: key,
Expand Down
37 changes: 36 additions & 1 deletion configuration/transport/http/doc.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,41 @@ package http

import "dictionaries-service/configuration"

// swagger:parameters updateConfigValue
type updateValueInTimeRequestWrapper struct {

// optional tenant id
// in:header
Tenant string `json:"X-Tenant-ID"`

// Config entry key
// in:path
Key string `json:"key"`

// date from
// in:path
From string `json:"from"`

// Configuration value
// in:body
Body updateValueInTimeRequest
}

// swagger:parameters addNewConfigEntry
type addNewConfigurationEntryRequestWrapper struct {

// optional tenant id
// in:header
Tenant string `json:"X-Tenant-ID"`

// in:path
Key string `json:"key"`

// Configuration body
// in:body
Body addNewConfigurationValueRequest
}

// swagger:parameters deleteConfigurationEntry
//goland:noinspection GoUnusedType
type deleteConfigurationEntryRequestWrapper struct {
Expand Down Expand Up @@ -73,7 +108,7 @@ type loadShortResponseWrapper struct {
type loadValuesResponseWrapper struct {

// in:body
Body []loadValueResponse
Body loadValueResponseFull
}

// swagger:response loadConfigurationOneResponseWrapper
Expand Down
122 changes: 111 additions & 11 deletions configuration/transport/http/endpoints.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"dictionaries-service/util"
"encoding/json"
"fmt"
slog "github.com/go-eden/slf4go"
"github.com/go-kit/kit/endpoint"
"github.com/gorilla/mux"
"net/http"
Expand Down Expand Up @@ -52,16 +53,33 @@ type saveConfigurationRequest struct {
DateTo types.JsonDate `json:"date_to"`
}

type addNewConfigurationValueRequest struct {
Value *string `json:"value"`
DateFrom types.JsonDate `json:"date_from"`
DateTo types.JsonDate `json:"date_to"`
}

type addNewConfigurationValueCompleted struct {
Key string `json:"key"`
addNewConfigurationValueRequest
}

type deleteConfigurationRequest struct {
Key string `json:"key"`
DateFrom types.JsonDate `json:"date_from"`
}

type loadValueResponse struct {
Key string `json:"key"`
Value *string `json:"value"`
DateFrom time.Time `json:"date_from"`
DateTo time.Time `json:"date_to"`
type loadValueResponseFull struct {
Key string `json:"key"`
Type string `json:"type"`
Name string `json:"name"`
Values []valueInTime `json:"values"`
}

type valueInTime struct {
Value *string `json:"value"`
DateFrom types.JsonDate `json:"date_from"`
DateTo types.JsonDate `json:"date_to"`
}

type loadConfigurationResponse struct {
Expand All @@ -70,6 +88,79 @@ type loadConfigurationResponse struct {
Type string `json:"type"`
}

type updateValueInTimeRequest struct {
Value *string `json:"value"`
}

type updateValueInTimeCompleted struct {
key string
from time.Time
updateValueInTimeRequest
}

func DecodeUpdateValueInTimeRequest(_ context.Context, r *http.Request) (interface{}, error) {

var request updateValueInTimeRequest
if err := json.NewDecoder(r.Body).Decode(&request); err != nil {
return nil, err
}

vars := mux.Vars(r)
key := vars["key"]
from, err := util.StringToDate(vars["from"])

if err != nil {
slog.Errorf("can't convert %s into date", vars["from"])
return nil, err
}

return updateValueInTimeCompleted{
key: key,
from: from,
updateValueInTimeRequest: request,
}, nil
}

func MakeUpdateValueInTimeEndpoint(configurationService configuration.Service) endpoint.Endpoint {
return func(ctx context.Context, request interface{}) (interface{}, error) {

req := request.(updateValueInTimeCompleted)
err := configurationService.UpdateValueInTime(ctx, req.key, req.from, req.Value)
if err != nil {
return commons.MakeRestError(fmt.Errorf("can't update in time value for given key: %s, and date: %s, %v", req.key, req.from, err),
"cant_add_new_in_time_entry")
}
return nil, nil
}
}

func DecodeAddNewConfigurationValueRequest(_ context.Context, r *http.Request) (interface{}, error) {
var request addNewConfigurationValueRequest
if err := json.NewDecoder(r.Body).Decode(&request); err != nil {
return nil, err
}

vars := mux.Vars(r)
key := vars["key"]

return addNewConfigurationValueCompleted{
Key: key,
addNewConfigurationValueRequest: request,
}, nil
}

func MakeAddNewConfigurationValueEndpoint(configurationService configuration.Service) endpoint.Endpoint {
return func(ctx context.Context, request interface{}) (interface{}, error) {

req := request.(addNewConfigurationValueCompleted)
if err := configurationService.AddNewValueInTime(ctx, req.Key, req.Value, req.DateFrom.Time(), req.DateTo.Time()); err != nil {
return commons.MakeRestError(fmt.Errorf("can't create new in time value for given key: %s, and date: %s, %v", req.Key, req.DateFrom, err),
"cant_add_new_in_time_value")
}
return nil, nil
}
}

func DecodeDeleteConfigurationRequest(_ context.Context, r *http.Request) (interface{}, error) {
var request deleteConfigurationRequest
if err := json.NewDecoder(r.Body).Decode(&request); err != nil {
Expand Down Expand Up @@ -173,23 +264,32 @@ func MakeLoadValuesEndpoint(configurationService configuration.Service) endpoint

req := request.(valuesRequest)

entry, err := configurationService.LoadEntry(ctx, req.Key)
if err != nil {
return commons.MakeRestError(err, "cant_delete_dictionary_entry")
}

values, err := configurationService.LoadValues(ctx, req.Key)
if err != nil {
return commons.MakeRestError(err, "cant_delete_dictionary_entry")
}

var res []loadValueResponse
var res []valueInTime

for _, v := range values {
res = append(res, loadValueResponse{
Key: v.Key,
res = append(res, valueInTime{
Value: util.SqlNullStringToStringPointer(v.Value),
DateFrom: v.DateFrom,
DateTo: v.DateTo,
DateFrom: types.JsonDate(v.DateFrom),
DateTo: types.JsonDate(v.DateTo),
})
}

return res, nil
return &loadValueResponseFull{
Key: entry.Key,
Type: entry.Type,
Name: entry.Name,
Values: res,
}, nil
}
}

Expand Down
Loading