1<?php 2/* 3 * 4 * Copyright 2018 gRPC authors. 5 * 6 * Licensed under the Apache License, Version 2.0 (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 * 18 */ 19/** 20 * Interface exported by the server. 21 */ 22require_once(dirname(__FILE__).'/../../lib/Grpc/BaseStub.php'); 23require_once(dirname(__FILE__).'/../../lib/Grpc/AbstractCall.php'); 24require_once(dirname(__FILE__).'/../../lib/Grpc/UnaryCall.php'); 25require_once(dirname(__FILE__).'/../../lib/Grpc/ClientStreamingCall.php'); 26require_once(dirname(__FILE__).'/../../lib/Grpc/Interceptor.php'); 27require_once(dirname(__FILE__).'/../../lib/Grpc/CallInvoker.php'); 28require_once(dirname(__FILE__).'/../../lib/Grpc/DefaultCallInvoker.php'); 29require_once(dirname(__FILE__).'/../../lib/Grpc/Internal/InterceptorChannel.php'); 30 31class CallInvokerSimpleRequest 32{ 33 private $data; 34 public function __construct($data) 35 { 36 $this->data = $data; 37 } 38 public function setData($data) 39 { 40 $this->data = $data; 41 } 42 public function serializeToString() 43 { 44 return $this->data; 45 } 46} 47 48class CallInvokerClient extends Grpc\BaseStub 49{ 50 51 /** 52 * @param string $hostname hostname 53 * @param array $opts channel options 54 * @param Channel|InterceptorChannel $channel (optional) re-use channel object 55 */ 56 public function __construct($hostname, $opts, $channel = null) 57 { 58 parent::__construct($hostname, $opts, $channel); 59 } 60 61 /** 62 * A simple RPC. 63 * @param SimpleRequest $argument input argument 64 * @param array $metadata metadata 65 * @param array $options call options 66 */ 67 public function UnaryCall( 68 CallInvokerSimpleRequest $argument, 69 $metadata = [], 70 $options = [] 71 ) { 72 return $this->_simpleRequest( 73 '/dummy_method', 74 $argument, 75 [], 76 $metadata, 77 $options 78 ); 79 } 80} 81 82class CallInvokerUpdateChannel implements \Grpc\CallInvoker 83{ 84 private $channel; 85 86 public function getChannel() { 87 return $this->channel; 88 } 89 90 public function createChannelFactory($hostname, $opts) { 91 $this->channel = new \Grpc\Channel('localhost:50050', $opts); 92 return $this->channel; 93 } 94 95 public function UnaryCall($channel, $method, $deserialize, $options) { 96 return new UnaryCall($channel, $method, $deserialize, $options); 97 } 98 99 public function ClientStreamingCall($channel, $method, $deserialize, $options) { 100 return new ClientStreamingCall($channel, $method, $deserialize, $options); 101 } 102 103 public function ServerStreamingCall($channel, $method, $deserialize, $options) { 104 return new ServerStreamingCall($channel, $method, $deserialize, $options); 105 } 106 107 public function BidiStreamingCall($channel, $method, $deserialize, $options) { 108 return new BidiStreamingCall($channel, $method, $deserialize, $options); 109 } 110} 111 112 113class CallInvokerChangeRequest implements \Grpc\CallInvoker 114{ 115 private $channel; 116 117 public function getChannel() { 118 return $this->channel; 119 } 120 public function createChannelFactory($hostname, $opts) { 121 $this->channel = new \Grpc\Channel($hostname, $opts); 122 return $this->channel; 123 } 124 125 public function UnaryCall($channel, $method, $deserialize, $options) { 126 return new CallInvokerChangeRequestCall($channel, $method, $deserialize, $options); 127 } 128 129 public function ClientStreamingCall($channel, $method, $deserialize, $options) { 130 return new ClientStreamingCall($channel, $method, $deserialize, $options); 131 } 132 133 public function ServerStreamingCall($channel, $method, $deserialize, $options) { 134 return new ServerStreamingCall($channel, $method, $deserialize, $options); 135 } 136 137 public function BidiStreamingCall($channel, $method, $deserialize, $options) { 138 return new BidiStreamingCall($channel, $method, $deserialize, $options); 139 } 140} 141 142class CallInvokerChangeRequestCall 143{ 144 private $call; 145 146 public function __construct($channel, $method, $deserialize, $options) 147 { 148 $this->call = new \Grpc\UnaryCall($channel, $method, $deserialize, $options); 149 } 150 151 public function start($argument, $metadata, $options) { 152 $argument->setData('intercepted_unary_request'); 153 $this->call->start($argument, $metadata, $options); 154 } 155 156 public function wait() 157 { 158 return $this->call->wait(); 159 } 160} 161 162class CallInvokerTest extends PHPUnit_Framework_TestCase 163{ 164 public function setUp() 165 { 166 $this->server = new Grpc\Server([]); 167 $this->port = $this->server->addHttp2Port('0.0.0.0:0'); 168 $this->server->start(); 169 } 170 171 public function tearDown() 172 { 173 unset($this->server); 174 } 175 176 public function testCreateDefaultCallInvoker() 177 { 178 $call_invoker = new \Grpc\DefaultCallInvoker(); 179 } 180 181 public function testCreateCallInvoker() 182 { 183 $call_invoker = new CallInvokerUpdateChannel(); 184 } 185 186 public function testCallInvokerAccessChannel() 187 { 188 $call_invoker = new CallInvokerUpdateChannel(); 189 $stub = new \Grpc\BaseStub('localhost:50051', 190 ['credentials' => \Grpc\ChannelCredentials::createInsecure(), 191 'grpc_call_invoker' => $call_invoker]); 192 $this->assertEquals($call_invoker->getChannel()->getTarget(), 'localhost:50050'); 193 $call_invoker->getChannel()->close(); 194 } 195 196 public function testClientChangeRequestCallInvoker() 197 { 198 $req_text = 'client_request'; 199 $call_invoker = new CallInvokerChangeRequest(); 200 $client = new CallInvokerClient('localhost:'.$this->port, [ 201 'force_new' => true, 202 'credentials' => Grpc\ChannelCredentials::createInsecure(), 203 'grpc_call_invoker' => $call_invoker, 204 ]); 205 206 $req = new CallInvokerSimpleRequest($req_text); 207 $unary_call = $client->UnaryCall($req); 208 209 $event = $this->server->requestCall(); 210 $this->assertSame('/dummy_method', $event->method); 211 $server_call = $event->call; 212 $event = $server_call->startBatch([ 213 Grpc\OP_SEND_INITIAL_METADATA => [], 214 Grpc\OP_SEND_STATUS_FROM_SERVER => [ 215 'metadata' => [], 216 'code' => Grpc\STATUS_OK, 217 'details' => '', 218 ], 219 Grpc\OP_RECV_MESSAGE => true, 220 Grpc\OP_RECV_CLOSE_ON_SERVER => true, 221 ]); 222 $this->assertSame('intercepted_unary_request', $event->message); 223 $call_invoker->getChannel()->close(); 224 unset($unary_call); 225 unset($server_call); 226 } 227} 228