1 /*
2  * Copyright 2018, OpenCensus 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.opencensus.exporter.trace.stackdriver;
18 
19 import com.google.auth.Credentials;
20 import com.google.auto.value.AutoValue;
21 import com.google.cloud.ServiceOptions;
22 import com.google.cloud.trace.v2.stub.TraceServiceStub;
23 import com.google.common.annotations.VisibleForTesting;
24 import com.google.common.base.Preconditions;
25 import com.google.common.base.Strings;
26 import io.opencensus.common.Duration;
27 import io.opencensus.trace.AttributeValue;
28 import java.util.Collections;
29 import java.util.LinkedHashMap;
30 import java.util.Map;
31 import javax.annotation.Nullable;
32 import javax.annotation.concurrent.Immutable;
33 
34 /**
35  * Configurations for {@link StackdriverTraceExporter}.
36  *
37  * @since 0.12
38  */
39 @AutoValue
40 @Immutable
41 public abstract class StackdriverTraceConfiguration {
42 
43   private static final String DEFAULT_PROJECT_ID =
44       Strings.nullToEmpty(ServiceOptions.getDefaultProjectId());
45 
46   @VisibleForTesting static final Duration DEFAULT_DEADLINE = Duration.create(10, 0);
47 
StackdriverTraceConfiguration()48   StackdriverTraceConfiguration() {}
49 
50   /**
51    * Returns the {@link Credentials}.
52    *
53    * @return the {@code Credentials}.
54    * @since 0.12
55    */
56   @Nullable
getCredentials()57   public abstract Credentials getCredentials();
58 
59   /**
60    * Returns the cloud project id.
61    *
62    * @return the cloud project id.
63    * @since 0.12
64    */
getProjectId()65   public abstract String getProjectId();
66 
67   /**
68    * Returns a TraceServiceStub instance used to make RPC calls.
69    *
70    * @return the trace service stub.
71    * @since 0.16
72    */
73   @Nullable
getTraceServiceStub()74   public abstract TraceServiceStub getTraceServiceStub();
75 
76   /**
77    * Returns a map of attributes that is added to all the exported spans.
78    *
79    * @return the map of attributes that is added to all the exported spans.
80    * @since 0.19
81    */
getFixedAttributes()82   public abstract Map<String, AttributeValue> getFixedAttributes();
83 
84   /**
85    * Returns the deadline for exporting to Stackdriver Trace backend.
86    *
87    * <p>Default value is 10 seconds.
88    *
89    * @return the export deadline.
90    * @since 0.22
91    */
getDeadline()92   public abstract Duration getDeadline();
93 
94   /**
95    * Returns a new {@link Builder}.
96    *
97    * @return a {@code Builder}.
98    * @since 0.12
99    */
builder()100   public static Builder builder() {
101     return new AutoValue_StackdriverTraceConfiguration.Builder()
102         .setProjectId(DEFAULT_PROJECT_ID)
103         .setFixedAttributes(Collections.<String, AttributeValue>emptyMap())
104         .setDeadline(DEFAULT_DEADLINE);
105   }
106 
107   /**
108    * Builder for {@link StackdriverTraceConfiguration}.
109    *
110    * @since 0.12
111    */
112   @AutoValue.Builder
113   public abstract static class Builder {
114 
115     @VisibleForTesting static final Duration ZERO = Duration.fromMillis(0);
116 
Builder()117     Builder() {}
118 
119     /**
120      * Sets the {@link Credentials} used to authenticate API calls.
121      *
122      * @param credentials the {@code Credentials}.
123      * @return this.
124      * @since 0.12
125      */
setCredentials(Credentials credentials)126     public abstract Builder setCredentials(Credentials credentials);
127 
128     /**
129      * Sets the cloud project id.
130      *
131      * @param projectId the cloud project id.
132      * @return this.
133      * @since 0.12
134      */
setProjectId(String projectId)135     public abstract Builder setProjectId(String projectId);
136 
137     /**
138      * Sets the trace service stub used to send gRPC calls.
139      *
140      * @param traceServiceStub the {@code TraceServiceStub}.
141      * @return this.
142      * @since 0.16
143      */
setTraceServiceStub(TraceServiceStub traceServiceStub)144     public abstract Builder setTraceServiceStub(TraceServiceStub traceServiceStub);
145 
146     /**
147      * Sets the map of attributes that is added to all the exported spans.
148      *
149      * @param fixedAttributes the map of attributes that is added to all the exported spans.
150      * @return this.
151      * @since 0.16
152      */
setFixedAttributes(Map<String, AttributeValue> fixedAttributes)153     public abstract Builder setFixedAttributes(Map<String, AttributeValue> fixedAttributes);
154 
155     /**
156      * Sets the deadline for exporting to Stackdriver Trace backend.
157      *
158      * <p>If both {@code TraceServiceStub} and {@code Deadline} are set, {@code TraceServiceStub}
159      * takes precedence and {@code Deadline} will not be respected.
160      *
161      * @param deadline the export deadline.
162      * @return this
163      * @since 0.22
164      */
setDeadline(Duration deadline)165     public abstract Builder setDeadline(Duration deadline);
166 
getProjectId()167     abstract String getProjectId();
168 
getFixedAttributes()169     abstract Map<String, AttributeValue> getFixedAttributes();
170 
getDeadline()171     abstract Duration getDeadline();
172 
autoBuild()173     abstract StackdriverTraceConfiguration autoBuild();
174 
175     /**
176      * Builds a {@link StackdriverTraceConfiguration}.
177      *
178      * @return a {@code StackdriverTraceConfiguration}.
179      * @since 0.12
180      */
build()181     public StackdriverTraceConfiguration build() {
182       // Make a defensive copy of fixed attributes.
183       setFixedAttributes(
184           Collections.unmodifiableMap(
185               new LinkedHashMap<String, AttributeValue>(getFixedAttributes())));
186       Preconditions.checkArgument(
187           !Strings.isNullOrEmpty(getProjectId()),
188           "Cannot find a project ID from either configurations or application default.");
189       for (Map.Entry<String, AttributeValue> fixedAttribute : getFixedAttributes().entrySet()) {
190         Preconditions.checkNotNull(fixedAttribute.getKey(), "attribute key");
191         Preconditions.checkNotNull(fixedAttribute.getValue(), "attribute value");
192       }
193       Preconditions.checkArgument(getDeadline().compareTo(ZERO) > 0, "Deadline must be positive.");
194       return autoBuild();
195     }
196   }
197 }
198