blob: 47d79131ba138d29b8f24a5d06ca29ce5f9977ad [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cache
import (
"fmt"
)
import (
envoy_types "github.com/envoyproxy/go-control-plane/pkg/cache/types"
envoy_cache "github.com/envoyproxy/go-control-plane/pkg/cache/v3"
)
import (
mesh_proto "github.com/apache/dubbo-kubernetes/api/mesh/v1alpha1"
core_model "github.com/apache/dubbo-kubernetes/pkg/core/resources/model"
"github.com/apache/dubbo-kubernetes/pkg/dds/util"
)
type (
ResourceVersionMap map[core_model.ResourceType]util.NameToVersion
)
// Snapshot is an internally consistent snapshot of xDS resources.
type Snapshot struct {
Resources map[core_model.ResourceType]envoy_cache.Resources
// VersionMap holds the current hash map of all resources in the snapshot.
// This field should remain nil until it is used, at which point should be
// instantiated by calling ConstructVersionMap().
// VersionMap is only to be used with delta xDS.
VersionMap ResourceVersionMap
}
var _ envoy_cache.ResourceSnapshot = &Snapshot{}
func (s *Snapshot) GetResources(typ string) map[string]envoy_types.Resource {
if s == nil {
return nil
}
resources := s.GetResourcesAndTTL(typ)
if resources == nil {
return nil
}
withoutTtl := make(map[string]envoy_types.Resource, len(resources))
for name, res := range resources {
withoutTtl[name] = res.Resource
}
return withoutTtl
}
func (s *Snapshot) GetResourcesAndTTL(typ string) map[string]envoy_types.ResourceWithTTL {
if s == nil {
return nil
}
if r, ok := s.Resources[core_model.ResourceType(typ)]; ok {
return r.Items
}
return nil
}
func (s *Snapshot) GetVersion(typ string) string {
if s == nil {
return ""
}
if r, ok := s.Resources[core_model.ResourceType(typ)]; ok {
return r.Version
}
return ""
}
func (s *Snapshot) GetVersionMap(typeURL string) map[string]string {
return s.VersionMap[core_model.ResourceType(typeURL)]
}
// ConstructVersionMap will construct a version map based on the current state of a snapshot
func (s *Snapshot) ConstructVersionMap() error {
if s == nil {
return fmt.Errorf("missing snapshot")
}
// The snapshot resources never change, so no need to ever rebuild.
if s.VersionMap != nil {
return nil
}
s.VersionMap = make(ResourceVersionMap)
for typeURL, resources := range s.Resources {
if _, ok := s.VersionMap[typeURL]; !ok {
s.VersionMap[typeURL] = make(util.NameToVersion)
}
for _, r := range resources.Items {
// Hash our version in here and build the version map.
marshaledResource, err := envoy_cache.MarshalResource(r.Resource)
if err != nil {
return err
}
v := envoy_cache.HashResource(marshaledResource)
if v == "" {
return fmt.Errorf("failed to build resource version: %w", err)
}
s.VersionMap[typeURL][GetResourceName(r.Resource)] = v
}
}
return nil
}
func GetResourceName(res envoy_types.Resource) string {
switch v := res.(type) {
case *mesh_proto.DubboResource:
return fmt.Sprintf("%s.%s", v.GetMeta().GetName(), v.GetMeta().GetMesh())
default:
return ""
}
}
// IndexResourcesByName creates a map from the resource name to the resource. Name should be unique
// across meshes that's why Name is <name>.<mesh>
func IndexResourcesByName(items []envoy_types.ResourceWithTTL) map[string]envoy_types.ResourceWithTTL {
indexed := make(map[string]envoy_types.ResourceWithTTL, len(items))
for _, item := range items {
key := GetResourceName(item.Resource)
indexed[key] = item
}
return indexed
}