66#endif
77using System . Net . Http . Headers ;
88using OpenTelemetry . Exporter . OpenTelemetryProtocol . Implementation . ExportClient . Grpc ;
9- using OpenTelemetry . Internal ;
109
1110namespace OpenTelemetry . Exporter . OpenTelemetryProtocol . Implementation . ExportClient ;
1211
1312/// <summary>Base class for sending OTLP export request over gRPC.</summary>
14- internal sealed class ProtobufOtlpGrpcExportClient : IProtobufExportClient
13+ internal sealed class ProtobufOtlpGrpcExportClient : ProtobufOtlpExportClient
1514{
1615 public const string GrpcStatusDetailsHeader = "grpc-status-details-bin" ;
1716 private static readonly ExportClientHttpResponse SuccessExportResponse = new ( success : true , deadlineUtc : default , response : null , exception : null ) ;
1817 private static readonly MediaTypeHeaderValue MediaHeaderValue = new ( "application/grpc" ) ;
19- private static readonly Version Http2RequestVersion = new ( 2 , 0 ) ;
2018
2119 private static readonly ExportClientGrpcResponse DefaultExceptionExportClientGrpcResponse
2220 = new (
@@ -27,49 +25,34 @@ private static readonly ExportClientGrpcResponse DefaultExceptionExportClientGrp
2725 grpcStatusDetailsHeader : null ) ;
2826
2927 public ProtobufOtlpGrpcExportClient ( OtlpExporterOptions options , HttpClient httpClient , string signalPath )
28+ : base ( options , httpClient , signalPath )
3029 {
31- Guard . ThrowIfNull ( options ) ;
32- Guard . ThrowIfNull ( httpClient ) ;
33- Guard . ThrowIfNull ( signalPath ) ;
34- Guard . ThrowIfInvalidTimeout ( options . TimeoutMilliseconds ) ;
35-
36- Uri exporterEndpoint = options . Endpoint . AppendPathIfNotPresent ( signalPath ) ;
37- this . Endpoint = new UriBuilder ( exporterEndpoint ) . Uri ;
38- this . Headers = options . GetHeaders < Dictionary < string , string > > ( ( d , k , v ) => d . Add ( k , v ) ) ;
39- this . HttpClient = httpClient ;
4030 }
4131
42- internal HttpClient HttpClient { get ; }
32+ internal override MediaTypeHeaderValue MediaTypeHeader => MediaHeaderValue ;
4333
44- internal Uri Endpoint { get ; set ; }
45-
46- internal IReadOnlyDictionary < string , string > Headers { get ; }
47-
48- internal int TimeoutMilliseconds { get ; }
34+ internal override bool RequireHttp2 => true ;
4935
5036 /// <inheritdoc/>
51- public ExportClientResponse SendExportRequest ( byte [ ] buffer , int contentLength , DateTime deadlineUtc , CancellationToken cancellationToken = default )
37+ public override ExportClientResponse SendExportRequest ( byte [ ] buffer , int contentLength , DateTime deadlineUtc , CancellationToken cancellationToken = default )
5238 {
5339 try
5440 {
5541 using var httpRequest = this . CreateHttpRequest ( buffer , contentLength ) ;
5642 using var httpResponse = this . SendHttpRequest ( httpRequest , cancellationToken ) ;
5743
58- try
59- {
60- httpResponse . EnsureSuccessStatusCode ( ) ;
61- }
62- catch ( HttpRequestException )
63- {
64- throw ;
65- }
44+ httpResponse . EnsureSuccessStatusCode ( ) ;
6645
6746 var trailingHeaders = httpResponse . TrailingHeaders ( ) ;
6847 Status status = GrpcProtocolHelpers . GetResponseStatus ( httpResponse , trailingHeaders ) ;
6948
7049 if ( status . Detail . Equals ( Status . NoReplyDetailMessage ) )
7150 {
51+ #if NET
52+ using var responseStream = httpResponse . Content . ReadAsStream ( cancellationToken ) ;
53+ #else
7254 using var responseStream = httpResponse . Content . ReadAsStreamAsync ( ) . GetAwaiter ( ) . GetResult ( ) ;
55+ #endif
7356 int firstByte = responseStream . ReadByte ( ) ;
7457
7558 if ( firstByte == - 1 )
@@ -170,45 +153,11 @@ public ExportClientResponse SendExportRequest(byte[] buffer, int contentLength,
170153 }
171154 }
172155
173- public HttpRequestMessage CreateHttpRequest ( byte [ ] buffer , int contentLength )
174- {
175- var request = new HttpRequestMessage ( HttpMethod . Post , this . Endpoint ) ;
176- request . Version = Http2RequestVersion ;
177-
178- #if NET6_0_OR_GREATER
179- request . VersionPolicy = HttpVersionPolicy . RequestVersionExact ;
180- #endif
181-
182- foreach ( var header in this . Headers )
183- {
184- request . Headers . Add ( header . Key , header . Value ) ;
185- }
186-
187- // TODO: Support compression.
188-
189- request . Content = new ByteArrayContent ( buffer , 0 , contentLength ) ;
190- request . Content . Headers . ContentType = MediaHeaderValue ;
191-
192- return request ;
193- }
194-
195- public HttpResponseMessage SendHttpRequest ( HttpRequestMessage request , CancellationToken cancellationToken )
196- {
197- return this . HttpClient . SendAsync ( request , cancellationToken ) . GetAwaiter ( ) . GetResult ( ) ;
198- }
199-
200- /// <inheritdoc/>
201- public bool Shutdown ( int timeoutMilliseconds )
202- {
203- this . HttpClient . CancelPendingRequests ( ) ;
204- return true ;
205- }
206-
207156 private static bool IsTransientNetworkError ( HttpRequestException ex )
208157 {
209- return ex . InnerException is System . Net . Sockets . SocketException socketEx &&
210- ( socketEx . SocketErrorCode == System . Net . Sockets . SocketError . TimedOut ||
211- socketEx . SocketErrorCode == System . Net . Sockets . SocketError . ConnectionReset ||
212- socketEx . SocketErrorCode == System . Net . Sockets . SocketError . HostUnreachable ) ;
158+ return ex . InnerException is System . Net . Sockets . SocketException socketEx
159+ && ( socketEx . SocketErrorCode == System . Net . Sockets . SocketError . TimedOut
160+ || socketEx . SocketErrorCode == System . Net . Sockets . SocketError . ConnectionReset
161+ || socketEx . SocketErrorCode == System . Net . Sockets . SocketError . HostUnreachable ) ;
213162 }
214163}
0 commit comments