Skip to content
This repository has been archived by the owner on Oct 3, 2023. It is now read-only.

WIP: Add Grpc Interceptor and integration test #189

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Add integration test against grpc master with interceptor support
  • Loading branch information
chingor13 committed May 15, 2018
commit dcd1ce0857a1f90c457ab74b30f7a9229022b0fe
163 changes: 163 additions & 0 deletions src/Trace/Integrations/Grpc/TraceInterceptor.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
<?php
/**
* Copyright 2018 OpenCensus Authors
*
* Licensed 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.
*/

namespace OpenCensus\Trace\Integrations\Grpc;

use Grpc\Interceptor;
use OpenCensus\Trace\Propagator\PropagatorInterface;
use OpenCensus\Trace\Propagator\GrpcMetadataPropagator;
use OpenCensus\Trace\Span;
use OpenCensus\Trace\Tracer;

/**
* This interceptor creates a Span for each type of gRPC call and injects a
* metadata attribute to propagate SpanContext to downstream services.
*
* Example:
* ```
* $interceptor = new TraceInterceptor();
* $channel = new Grpc\Channel('127.0.0.1:1234');
* $channel = Grpc\Interceptor::intercept($channel, $interceptor);
* $client = new MyGrpcClient('127.0.0.1:1234', $channel);
* ```
*/
class TraceInterceptor extends Interceptor
{
/* @var PropagatorInterface */
private $propagator;

/**
* Create a new TraceInterceptor.
*
* @param PropagatorInterface $propagator The
*/
public function __construct($propagator = null)
{
$this->propagator = $propagator ?: new GrpcMetadataPropagator();
}

/**
* This interceptor is for simple unary requests.
*
* @param string $method The name of the method to call
* @param mixed $argument The argument to the method
* @param array $metadata A metadata map to send to the server (optional)
* @param array $options An array of options (optional)
* @param callable $continuation The next interceptor to call
*/
public function interceptUnaryUnary(
$method,
$argument,
array $metadata,
array $options,
$continuation
) {
$spanOptions = [
'name' => 'grpc/simpleRequest',
'attributes' => [
'method' => $method
],
'kind' => Span::KIND_CLIENT
];
$metadata = $this->injectMetadata($metadata);

return Tracer::inSpan($spanOptions, $continuation, [$method, $argument, $metadata, $options]);
}

/**
* This interceptor is for client streaming requests.
*
* @param string $method The name of the method to call
* @param array $metadata A metadata map to send to the server (optional)
* @param array $options An array of options (optional)
* @param callable $continuation The next interceptor to call
*/
public function interceptStreamUnary(
$method,
array $metadata,
array $options,
$continuation
) {
$spanOptions = [
'name' => 'grpc/clientStreamRequest',
'attributes' => [
'method' => $method
],
'kind' => Span::KIND_CLIENT
];
$metadata = $this->injectMetadata($metadata);
return Tracer::inSpan($spanOptions, $continuation, [$method, $metadata, $options]);
}

/**
* This interceptor is for server streaming requests.
*
* @param string $method The name of the method to call
* @param mixed $argument The argument to the method
* @param array $metadata A metadata map to send to the server (optional)
* @param array $options An array of options (optional)
* @param callable $continuation The next interceptor to call
*/
public function interceptUnaryStream(
$method,
$argument,
array $metadata,
array $options,
$continuation
) {
$spanOptions = [
'name' => 'grpc/serverStreamRequest',
'attributes' => [
'method' => $method
],
'kind' => Span::KIND_CLIENT
];
$metadata = $this->injectMetadata($metadata);
return Tracer::inSpan($spanOptions, $continuation, [$method, $argument, $metadata, $options]);
}

/**
* This interceptor is for server streaming requests.
*
* @param string $method The name of the method to call
* @param array $metadata A metadata map to send to the server (optional)
* @param array $options An array of options (optional)
* @param callable $continuation The next interceptor to call
*/
public function interceptStreamStream(
$method,
array $metadata,
array $options,
$continuation
) {
$spanOptions = [
'name' => 'grpc/bidiRequest',
'attributes' => [
'method' => $method
],
'kind' => Span::KIND_CLIENT
];
$metadata = $this->injectMetadata($metadata);
return Tracer::inSpan($spanOptions, $continuation, [$method, $metadata, $options]);
}

private function injectMetadata(array $metadata)
{
$context = Tracer::spanContext();
return $this->propagator->inject($context, $metadata);
}
}
2 changes: 1 addition & 1 deletion src/Trace/Propagator/GrpcMetadataPropagator.php
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ public function extract($metadata)
*/
public function inject(SpanContext $context, $metadata)
{
$metadata[$this->key] = $this->formatter->serialize($context);
$metadata[$this->key] = [$this->formatter->serialize($context)];
return $metadata;
}

Expand Down
22 changes: 22 additions & 0 deletions tests/integration/grpc/composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"require": {
"php": "^7.2",
"opencensus/opencensus": "dev-master",
"grpc/grpc": "dev-master",
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO: fix this dependency when grpc is released with interceptors

"ext-opencensus": "*",
"ext-grpc": "*"
},
"require-dev": {
"phpunit/phpunit": "^7.0"
},
"repositories": {
"opencensus": {
"type": "git",
"url": "https://github.com/census-instrumentation/opencensus-php"
},
"grpc": {
"type": "git",
"url": "https://github.com/grpc/grpc"
}
}
}
13 changes: 13 additions & 0 deletions tests/integration/grpc/phpunit.xml.dist
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit bootstrap="./vendor/autoload.php" colors="true">
<testsuites>
<testsuite>
<directory>tests</directory>
</testsuite>
</testsuites>
<filter>
<whitelist>
<directory suffix=".php">src</directory>
</whitelist>
</filter>
</phpunit>
27 changes: 27 additions & 0 deletions tests/integration/grpc/test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#!/bin/bash
# Copyright 2018 OpenCensus Authors
#
# Licensed 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.

set -e

pushd $(dirname ${BASH_SOURCE[0]})
source ../setup_test_repo.sh

sed -i "s|dev-master|dev-${BRANCH}|" composer.json
sed -i "s|https://github.com/census-instrumentation/opencensus-php|${REPO}|" composer.json
composer install -n --prefer-dist

vendor/bin/phpunit

popd
Loading