bcfd33d9fb
Previously UN-LOCODE attribute was required for each network map candidate. In the absence of this attribute, the candidate was not allowed into the network map. After revising the requirements for candidates, it was decided not to require the mandatory installation of the attribute by candidates. From now inner ring does not modify location attributes of the network map candidate in the absence of UN-LOCODE attribute and does not block entry into the network map for this criterion. Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
84 lines
2 KiB
Go
84 lines
2 KiB
Go
package locode
|
|
|
|
import (
|
|
"github.com/nspcc-dev/neofs-api-go/pkg/netmap"
|
|
"github.com/nspcc-dev/neofs-node/pkg/util/locode"
|
|
"github.com/pkg/errors"
|
|
)
|
|
|
|
var errMissingRequiredAttr = errors.New("missing required attribute in DB record")
|
|
|
|
// VerifyAndUpdate validates UN-LOCODE attribute of n
|
|
// and adds a group of related attributes.
|
|
//
|
|
// If n does not contain UN-LOCODE attribute, nil is returned
|
|
// without any actions. Otherwise, if UN-LOCODE value does not
|
|
// match the UN/LOCODE format, an error returns.
|
|
//
|
|
// New attributes are formed from the record of DB instance (Prm).
|
|
// If DB entry R was found w/o errors, then new attributes are:
|
|
// * CountryCode: R.CountryCode().String();
|
|
// * Country: R.CountryName();
|
|
// * LocationCode: R.LocationCode().String();
|
|
// * Location: Record.LocationName();
|
|
// * SubDivCode: R.SubDivCode();
|
|
// * SubDiv: R.SubDivName();
|
|
// * Continent: R.Continent().String().
|
|
//
|
|
// UN-LOCODE attribute remains untouched.
|
|
func (v *Validator) VerifyAndUpdate(n *netmap.NodeInfo) error {
|
|
mAttr := uniqueAttributes(n.Attributes())
|
|
|
|
attrLocode, ok := mAttr[netmap.AttrUNLOCODE]
|
|
if !ok {
|
|
return nil
|
|
}
|
|
|
|
lc, err := locode.FromString(attrLocode.Value())
|
|
if err != nil {
|
|
return errors.Wrap(err, "invalid locode value")
|
|
}
|
|
|
|
record, err := v.db.Get(lc)
|
|
if err != nil {
|
|
return errors.Wrap(err, "could not get locode record from DB")
|
|
}
|
|
|
|
for attrKey, attrDesc := range v.mAttr {
|
|
attrVal := attrDesc.converter(record)
|
|
if attrVal == "" {
|
|
if !attrDesc.optional {
|
|
return errMissingRequiredAttr
|
|
}
|
|
|
|
continue
|
|
}
|
|
|
|
a := netmap.NewNodeAttribute()
|
|
a.SetKey(attrKey)
|
|
a.SetValue(attrVal)
|
|
|
|
mAttr[attrKey] = a
|
|
}
|
|
|
|
as := n.Attributes()
|
|
as = as[:0]
|
|
|
|
for _, attr := range mAttr {
|
|
as = append(as, attr)
|
|
}
|
|
|
|
n.SetAttributes(as...)
|
|
|
|
return nil
|
|
}
|
|
|
|
func uniqueAttributes(as []*netmap.NodeAttribute) map[string]*netmap.NodeAttribute {
|
|
mAttr := make(map[string]*netmap.NodeAttribute, len(as))
|
|
|
|
for _, attr := range as {
|
|
mAttr[attr.Key()] = attr
|
|
}
|
|
|
|
return mAttr
|
|
}
|