• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2020 The gRPC Authors
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package io.grpc.xds;
18 
19 import static com.google.common.base.Preconditions.checkNotNull;
20 
21 import io.grpc.Attributes;
22 import io.grpc.EquivalentAddressGroup;
23 import io.grpc.NameResolver.ResolutionResultAttr;
24 import java.util.ArrayList;
25 import java.util.Collections;
26 import java.util.List;
27 import javax.annotation.Nullable;
28 
29 final class AddressFilter {
30   @ResolutionResultAttr
31   private static final Attributes.Key<PathChain> PATH_CHAIN_KEY =
32       Attributes.Key.create("io.grpc.xds.AddressFilter.PATH_CHAIN_KEY");
33 
34   // Prevent instantiation.
AddressFilter()35   private AddressFilter() {}
36 
37   /**
38    * Returns a new EquivalentAddressGroup by setting a path filter to the given
39    * EquivalentAddressGroup. This method does not modify the input address.
40    */
setPathFilter(EquivalentAddressGroup address, List<String> names)41   static EquivalentAddressGroup setPathFilter(EquivalentAddressGroup address, List<String> names) {
42     checkNotNull(address, "address");
43     checkNotNull(names, "names");
44     Attributes.Builder attrBuilder = address.getAttributes().toBuilder().discard(PATH_CHAIN_KEY);
45     PathChain pathChain = null;
46     for (String name : names) {
47       if (pathChain == null) {
48         pathChain = new PathChain(name);
49         attrBuilder.set(PATH_CHAIN_KEY, pathChain);
50       } else {
51         pathChain.next = new PathChain(name);
52       }
53     }
54     return new EquivalentAddressGroup(address.getAddresses(), attrBuilder.build());
55   }
56 
57   /**
58    * Returns the next level hierarchical addresses derived from the given hierarchical addresses
59    * with the given filter name (any non-hierarchical addresses in the input will be ignored).
60    * This method does not modify the input addresses.
61    */
filter(List<EquivalentAddressGroup> addresses, String name)62   static List<EquivalentAddressGroup> filter(List<EquivalentAddressGroup> addresses, String name) {
63     checkNotNull(addresses, "addresses");
64     checkNotNull(name, "name");
65     List<EquivalentAddressGroup> filteredAddresses = new ArrayList<>();
66     for (EquivalentAddressGroup address : addresses) {
67       PathChain pathChain = address.getAttributes().get(PATH_CHAIN_KEY);
68       if (pathChain != null && pathChain.name.equals(name)) {
69         Attributes filteredAddressAttrs =
70             address.getAttributes().toBuilder().set(PATH_CHAIN_KEY, pathChain.next).build();
71         filteredAddresses.add(
72             new EquivalentAddressGroup(address.getAddresses(), filteredAddressAttrs));
73       }
74     }
75     return Collections.unmodifiableList(filteredAddresses);
76   }
77 
78   private static final class PathChain {
79     final String name;
80     @Nullable PathChain next;
81 
PathChain(String name)82     PathChain(String name) {
83       this.name = checkNotNull(name, "name");
84     }
85 
86     @Override
toString()87     public String toString() {
88       return name + (next == null ? "" : ", " + next);
89     }
90   }
91 }
92