|  | 
|  | 1 | +/* | 
|  | 2 | + * Copyright The OpenTelemetry Authors | 
|  | 3 | + * SPDX-License-Identifier: Apache-2.0 | 
|  | 4 | + */ | 
|  | 5 | + | 
|  | 6 | +package io.opentelemetry.contrib.sampler.internal; | 
|  | 7 | + | 
|  | 8 | +import io.opentelemetry.api.common.AttributeKey; | 
|  | 9 | +import io.opentelemetry.api.trace.SpanKind; | 
|  | 10 | +import io.opentelemetry.contrib.sampler.RuleBasedRoutingSampler; | 
|  | 11 | +import io.opentelemetry.contrib.sampler.RuleBasedRoutingSamplerBuilder; | 
|  | 12 | +import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; | 
|  | 13 | +import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider; | 
|  | 14 | +import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; | 
|  | 15 | +import io.opentelemetry.sdk.extension.incubator.fileconfig.FileConfiguration; | 
|  | 16 | +import io.opentelemetry.sdk.trace.samplers.Sampler; | 
|  | 17 | +import java.util.List; | 
|  | 18 | + | 
|  | 19 | +/** | 
|  | 20 | + * Declarative configuration SPI implementation for {@link RuleBasedRoutingSampler}. | 
|  | 21 | + * | 
|  | 22 | + * <p>This class is internal and is hence not for public use. Its APIs are unstable and can change | 
|  | 23 | + * at any time. | 
|  | 24 | + */ | 
|  | 25 | +public class RuleBasedRoutingSamplerComponentProvider implements ComponentProvider<Sampler> { | 
|  | 26 | + | 
|  | 27 | +  private static final String ACTION_RECORD_AND_SAMPLE = "RECORD_AND_SAMPLE"; | 
|  | 28 | +  private static final String ACTION_DROP = "DROP"; | 
|  | 29 | + | 
|  | 30 | +  @Override | 
|  | 31 | +  public Class<Sampler> getType() { | 
|  | 32 | +    return Sampler.class; | 
|  | 33 | +  } | 
|  | 34 | + | 
|  | 35 | +  @Override | 
|  | 36 | +  public String getName() { | 
|  | 37 | +    return "rule_based_routing"; | 
|  | 38 | +  } | 
|  | 39 | + | 
|  | 40 | +  @Override | 
|  | 41 | +  public Sampler create(StructuredConfigProperties config) { | 
|  | 42 | +    StructuredConfigProperties fallbackModel = config.getStructured("fallback_sampler"); | 
|  | 43 | +    if (fallbackModel == null) { | 
|  | 44 | +      throw new ConfigurationException( | 
|  | 45 | +          "rule_based_routing sampler .fallback is required but is null"); | 
|  | 46 | +    } | 
|  | 47 | +    Sampler fallbackSampler; | 
|  | 48 | +    try { | 
|  | 49 | +      fallbackSampler = FileConfiguration.createSampler(fallbackModel); | 
|  | 50 | +    } catch (ConfigurationException e) { | 
|  | 51 | +      throw new ConfigurationException( | 
|  | 52 | +          "rule_Based_routing sampler failed to create .fallback sampler", e); | 
|  | 53 | +    } | 
|  | 54 | + | 
|  | 55 | +    String spanKindString = config.getString("span_kind", "SERVER"); | 
|  | 56 | +    SpanKind spanKind; | 
|  | 57 | +    try { | 
|  | 58 | +      spanKind = SpanKind.valueOf(spanKindString); | 
|  | 59 | +    } catch (IllegalArgumentException e) { | 
|  | 60 | +      throw new ConfigurationException( | 
|  | 61 | +          "rule_based_routing sampler .span_kind is invalid: " + spanKindString, e); | 
|  | 62 | +    } | 
|  | 63 | + | 
|  | 64 | +    RuleBasedRoutingSamplerBuilder builder = | 
|  | 65 | +        RuleBasedRoutingSampler.builder(spanKind, fallbackSampler); | 
|  | 66 | + | 
|  | 67 | +    List<StructuredConfigProperties> rules = config.getStructuredList("rules"); | 
|  | 68 | +    if (rules == null || rules.isEmpty()) { | 
|  | 69 | +      throw new ConfigurationException("rule_based_routing sampler .rules is required"); | 
|  | 70 | +    } | 
|  | 71 | + | 
|  | 72 | +    for (StructuredConfigProperties rule : rules) { | 
|  | 73 | +      String attribute = rule.getString("attribute"); | 
|  | 74 | +      if (attribute == null) { | 
|  | 75 | +        throw new ConfigurationException( | 
|  | 76 | +            "rule_based_routing sampler .rules[].attribute is required"); | 
|  | 77 | +      } | 
|  | 78 | +      AttributeKey<String> attributeKey = AttributeKey.stringKey(attribute); | 
|  | 79 | +      String pattern = rule.getString("pattern"); | 
|  | 80 | +      if (pattern == null) { | 
|  | 81 | +        throw new ConfigurationException("rule_based_routing sampler .rules[].pattern is required"); | 
|  | 82 | +      } | 
|  | 83 | +      String action = rule.getString("action"); | 
|  | 84 | +      if (action == null) { | 
|  | 85 | +        throw new ConfigurationException("rule_based_routing sampler .rules[].action is required"); | 
|  | 86 | +      } | 
|  | 87 | +      if (action.equals(ACTION_RECORD_AND_SAMPLE)) { | 
|  | 88 | +        builder.recordAndSample(attributeKey, pattern); | 
|  | 89 | +      } else if (action.equals(ACTION_DROP)) { | 
|  | 90 | +        builder.drop(attributeKey, pattern); | 
|  | 91 | +      } else { | 
|  | 92 | +        throw new ConfigurationException( | 
|  | 93 | +            "rule_based_routing sampler .rules[].action is must be " | 
|  | 94 | +                + ACTION_RECORD_AND_SAMPLE | 
|  | 95 | +                + " or " | 
|  | 96 | +                + ACTION_DROP); | 
|  | 97 | +      } | 
|  | 98 | +    } | 
|  | 99 | + | 
|  | 100 | +    return builder.build(); | 
|  | 101 | +  } | 
|  | 102 | +} | 
0 commit comments