mirror of https://github.com/grpc/grpc.git
parent
c75473fcef
commit
a7e282eecb
5 changed files with 336 additions and 13 deletions
@ -0,0 +1,33 @@ |
|||||||
|
<?php |
||||||
|
/* |
||||||
|
* |
||||||
|
* Copyright 2018 gRPC 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 Grpc; |
||||||
|
|
||||||
|
/** |
||||||
|
* CallInvoker is used to pass the self defined channel into the stub, |
||||||
|
* while intercept each RPC with the channel accessible. |
||||||
|
* THIS IS AN EXPERIMENTAL API. |
||||||
|
*/ |
||||||
|
interface CallInvoker |
||||||
|
{ |
||||||
|
public function createChannelFactory($hostname, $opts); |
||||||
|
public function UnaryCall($channel, $method, $deserialize, $options); |
||||||
|
public function ClientStreamingCall($channel, $method, $deserialize, $options); |
||||||
|
public function ServerStreamingCall($channel, $method, $deserialize, $options); |
||||||
|
public function BidiStreamingCall($channel, $method, $deserialize, $options); |
||||||
|
} |
@ -0,0 +1,47 @@ |
|||||||
|
<?php |
||||||
|
/* |
||||||
|
* |
||||||
|
* Copyright 2018 gRPC 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 Grpc; |
||||||
|
|
||||||
|
/** |
||||||
|
* Default call invoker in the gRPC stub. |
||||||
|
* THIS IS AN EXPERIMENTAL API. |
||||||
|
*/ |
||||||
|
class DefaultCallInvoker implements CallInvoker |
||||||
|
{ |
||||||
|
public function createChannelFactory($hostname, $opts) { |
||||||
|
return new Channel($hostname, $opts); |
||||||
|
} |
||||||
|
|
||||||
|
public function UnaryCall($channel, $method, $deserialize, $options) { |
||||||
|
return new UnaryCall($channel, $method, $deserialize, $options); |
||||||
|
} |
||||||
|
|
||||||
|
public function ClientStreamingCall($channel, $method, $deserialize, $options) { |
||||||
|
return new ClientStreamingCall($channel, $method, $deserialize, $options); |
||||||
|
} |
||||||
|
|
||||||
|
public function ServerStreamingCall($channel, $method, $deserialize, $options) { |
||||||
|
return new ServerStreamingCall($channel, $method, $deserialize, $options); |
||||||
|
} |
||||||
|
|
||||||
|
public function BidiStreamingCall($channel, $method, $deserialize, $options) { |
||||||
|
return new BidiStreamingCall($channel, $method, $deserialize, $options); |
||||||
|
} |
||||||
|
} |
||||||
|
|
@ -0,0 +1,227 @@ |
|||||||
|
<?php |
||||||
|
/* |
||||||
|
* |
||||||
|
* Copyright 2018 gRPC 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. |
||||||
|
* |
||||||
|
*/ |
||||||
|
/** |
||||||
|
* Interface exported by the server. |
||||||
|
*/ |
||||||
|
require_once(dirname(__FILE__).'/../../lib/Grpc/BaseStub.php'); |
||||||
|
require_once(dirname(__FILE__).'/../../lib/Grpc/AbstractCall.php'); |
||||||
|
require_once(dirname(__FILE__).'/../../lib/Grpc/UnaryCall.php'); |
||||||
|
require_once(dirname(__FILE__).'/../../lib/Grpc/ClientStreamingCall.php'); |
||||||
|
require_once(dirname(__FILE__).'/../../lib/Grpc/Interceptor.php'); |
||||||
|
require_once(dirname(__FILE__).'/../../lib/Grpc/CallInvoker.php'); |
||||||
|
require_once(dirname(__FILE__).'/../../lib/Grpc/DefaultCallInvoker.php'); |
||||||
|
require_once(dirname(__FILE__).'/../../lib/Grpc/Internal/InterceptorChannel.php'); |
||||||
|
|
||||||
|
class CallInvokerSimpleRequest |
||||||
|
{ |
||||||
|
private $data; |
||||||
|
public function __construct($data) |
||||||
|
{ |
||||||
|
$this->data = $data; |
||||||
|
} |
||||||
|
public function setData($data) |
||||||
|
{ |
||||||
|
$this->data = $data; |
||||||
|
} |
||||||
|
public function serializeToString() |
||||||
|
{ |
||||||
|
return $this->data; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
class CallInvokerClient extends Grpc\BaseStub |
||||||
|
{ |
||||||
|
|
||||||
|
/** |
||||||
|
* @param string $hostname hostname |
||||||
|
* @param array $opts channel options |
||||||
|
* @param Channel|InterceptorChannel $channel (optional) re-use channel object |
||||||
|
*/ |
||||||
|
public function __construct($hostname, $opts, $channel = null) |
||||||
|
{ |
||||||
|
parent::__construct($hostname, $opts, $channel); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* A simple RPC. |
||||||
|
* @param SimpleRequest $argument input argument |
||||||
|
* @param array $metadata metadata |
||||||
|
* @param array $options call options |
||||||
|
*/ |
||||||
|
public function UnaryCall( |
||||||
|
CallInvokerSimpleRequest $argument, |
||||||
|
$metadata = [], |
||||||
|
$options = [] |
||||||
|
) { |
||||||
|
return $this->_simpleRequest( |
||||||
|
'/dummy_method', |
||||||
|
$argument, |
||||||
|
[], |
||||||
|
$metadata, |
||||||
|
$options |
||||||
|
); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
class CallInvokerUpdateChannel implements \Grpc\CallInvoker |
||||||
|
{ |
||||||
|
private $channel; |
||||||
|
|
||||||
|
public function getChannel() { |
||||||
|
return $this->channel; |
||||||
|
} |
||||||
|
|
||||||
|
public function createChannelFactory($hostname, $opts) { |
||||||
|
$this->channel = new \Grpc\Channel('localhost:50050', $opts); |
||||||
|
return $this->channel; |
||||||
|
} |
||||||
|
|
||||||
|
public function UnaryCall($channel, $method, $deserialize, $options) { |
||||||
|
return new UnaryCall($channel, $method, $deserialize, $options); |
||||||
|
} |
||||||
|
|
||||||
|
public function ClientStreamingCall($channel, $method, $deserialize, $options) { |
||||||
|
return new ClientStreamingCall($channel, $method, $deserialize, $options); |
||||||
|
} |
||||||
|
|
||||||
|
public function ServerStreamingCall($channel, $method, $deserialize, $options) { |
||||||
|
return new ServerStreamingCall($channel, $method, $deserialize, $options); |
||||||
|
} |
||||||
|
|
||||||
|
public function BidiStreamingCall($channel, $method, $deserialize, $options) { |
||||||
|
return new BidiStreamingCall($channel, $method, $deserialize, $options); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
class CallInvokerChangeRequest implements \Grpc\CallInvoker |
||||||
|
{ |
||||||
|
private $channel; |
||||||
|
|
||||||
|
public function getChannel() { |
||||||
|
return $this->channel; |
||||||
|
} |
||||||
|
public function createChannelFactory($hostname, $opts) { |
||||||
|
$this->channel = new \Grpc\Channel($hostname, $opts); |
||||||
|
return $this->channel; |
||||||
|
} |
||||||
|
|
||||||
|
public function UnaryCall($channel, $method, $deserialize, $options) { |
||||||
|
return new CallInvokerChangeRequestCall($channel, $method, $deserialize, $options); |
||||||
|
} |
||||||
|
|
||||||
|
public function ClientStreamingCall($channel, $method, $deserialize, $options) { |
||||||
|
return new ClientStreamingCall($channel, $method, $deserialize, $options); |
||||||
|
} |
||||||
|
|
||||||
|
public function ServerStreamingCall($channel, $method, $deserialize, $options) { |
||||||
|
return new ServerStreamingCall($channel, $method, $deserialize, $options); |
||||||
|
} |
||||||
|
|
||||||
|
public function BidiStreamingCall($channel, $method, $deserialize, $options) { |
||||||
|
return new BidiStreamingCall($channel, $method, $deserialize, $options); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
class CallInvokerChangeRequestCall |
||||||
|
{ |
||||||
|
private $call; |
||||||
|
|
||||||
|
public function __construct($channel, $method, $deserialize, $options) |
||||||
|
{ |
||||||
|
$this->call = new \Grpc\UnaryCall($channel, $method, $deserialize, $options); |
||||||
|
} |
||||||
|
|
||||||
|
public function start($argument, $metadata, $options) { |
||||||
|
$argument->setData('intercepted_unary_request'); |
||||||
|
$this->call->start($argument, $metadata, $options); |
||||||
|
} |
||||||
|
|
||||||
|
public function wait() |
||||||
|
{ |
||||||
|
return $this->call->wait(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
class CallInvokerTest extends PHPUnit_Framework_TestCase |
||||||
|
{ |
||||||
|
public function setUp() |
||||||
|
{ |
||||||
|
$this->server = new Grpc\Server([]); |
||||||
|
$this->port = $this->server->addHttp2Port('0.0.0.0:0'); |
||||||
|
$this->server->start(); |
||||||
|
} |
||||||
|
|
||||||
|
public function tearDown() |
||||||
|
{ |
||||||
|
unset($this->server); |
||||||
|
} |
||||||
|
|
||||||
|
public function testCreateDefaultCallInvoker() |
||||||
|
{ |
||||||
|
$call_invoker = new \Grpc\DefaultCallInvoker(); |
||||||
|
} |
||||||
|
|
||||||
|
public function testCreateCallInvoker() |
||||||
|
{ |
||||||
|
$call_invoker = new CallInvokerUpdateChannel(); |
||||||
|
} |
||||||
|
|
||||||
|
public function testCallInvokerAccessChannel() |
||||||
|
{ |
||||||
|
$call_invoker = new CallInvokerUpdateChannel(); |
||||||
|
$stub = new \Grpc\BaseStub('localhost:50051', |
||||||
|
['credentials' => \Grpc\ChannelCredentials::createInsecure(), |
||||||
|
'grpc_call_invoker' => $call_invoker]); |
||||||
|
$this->assertEquals($call_invoker->getChannel()->getTarget(), 'localhost:50050'); |
||||||
|
$call_invoker->getChannel()->close(); |
||||||
|
} |
||||||
|
|
||||||
|
public function testClientChangeRequestCallInvoker() |
||||||
|
{ |
||||||
|
$req_text = 'client_request'; |
||||||
|
$call_invoker = new CallInvokerChangeRequest(); |
||||||
|
$client = new CallInvokerClient('localhost:'.$this->port, [ |
||||||
|
'force_new' => true, |
||||||
|
'credentials' => Grpc\ChannelCredentials::createInsecure(), |
||||||
|
'grpc_call_invoker' => $call_invoker, |
||||||
|
]); |
||||||
|
|
||||||
|
$req = new CallInvokerSimpleRequest($req_text); |
||||||
|
$unary_call = $client->UnaryCall($req); |
||||||
|
|
||||||
|
$event = $this->server->requestCall(); |
||||||
|
$this->assertSame('/dummy_method', $event->method); |
||||||
|
$server_call = $event->call; |
||||||
|
$event = $server_call->startBatch([ |
||||||
|
Grpc\OP_SEND_INITIAL_METADATA => [], |
||||||
|
Grpc\OP_SEND_STATUS_FROM_SERVER => [ |
||||||
|
'metadata' => [], |
||||||
|
'code' => Grpc\STATUS_OK, |
||||||
|
'details' => '', |
||||||
|
], |
||||||
|
Grpc\OP_RECV_MESSAGE => true, |
||||||
|
Grpc\OP_RECV_CLOSE_ON_SERVER => true, |
||||||
|
]); |
||||||
|
$this->assertSame('intercepted_unary_request', $event->message); |
||||||
|
$call_invoker->getChannel()->close(); |
||||||
|
unset($unary_call); |
||||||
|
unset($server_call); |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue