Jens Geyer | e8ca73f | 2014-03-24 21:41:12 +0200 | [diff] [blame] | 1 | <?php |
| 2 | /* |
| 3 | * Licensed to the Apache Software Foundation (ASF) under one |
| 4 | * or more contributor license agreements. See the NOTICE file |
| 5 | * distributed with this work for additional information |
| 6 | * regarding copyright ownership. The ASF licenses this file |
| 7 | * to you under the Apache License, Version 2.0 (the |
| 8 | * "License"); you may not use this file except in compliance |
| 9 | * with the License. You may obtain a copy of the License at |
| 10 | * |
| 11 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 12 | * |
| 13 | * Unless required by applicable law or agreed to in writing, |
| 14 | * software distributed under the License is distributed on an |
| 15 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| 16 | * KIND, either express or implied. See the License for the |
| 17 | * specific language governing permissions and limitations |
| 18 | * under the License. |
| 19 | * |
| 20 | * @package thrift.processor |
| 21 | */ |
| 22 | |
| 23 | namespace Thrift; |
| 24 | |
Jens Geyer | 8001421 | 2014-04-01 21:24:27 +0200 | [diff] [blame] | 25 | use Thrift\Exception\TException; |
Jens Geyer | e8ca73f | 2014-03-24 21:41:12 +0200 | [diff] [blame] | 26 | use Thrift\Protocol\TProtocol; |
| 27 | use Thrift\Protocol\TMultiplexedProtocol; |
Jens Geyer | e8ca73f | 2014-03-24 21:41:12 +0200 | [diff] [blame] | 28 | use Thrift\Type\TMessageType; |
| 29 | |
| 30 | /** |
| 31 | * <code>TMultiplexedProcessor</code> is a Processor allowing |
| 32 | * a single <code>TServer</code> to provide multiple services. |
| 33 | * |
| 34 | * <p>To do so, you instantiate the processor and then register additional |
| 35 | * processors with it, as shown in the following example:</p> |
| 36 | * |
| 37 | * <blockquote><code> |
| 38 | * $processor = new TMultiplexedProcessor(); |
| 39 | * |
| 40 | * processor->registerProcessor( |
| 41 | * "Calculator", |
| 42 | * new \tutorial\CalculatorProcessor(new CalculatorHandler())); |
| 43 | * |
| 44 | * processor->registerProcessor( |
| 45 | * "WeatherReport", |
| 46 | * new \tutorial\WeatherReportProcessor(new WeatherReportHandler())); |
| 47 | * |
| 48 | * $processor->process($protocol, $protocol); |
| 49 | * </code></blockquote> |
| 50 | */ |
| 51 | |
Roger Thomas | 6fb5923 | 2014-11-04 10:09:23 +0000 | [diff] [blame] | 52 | class TMultiplexedProcessor |
| 53 | { |
Jens Geyer | e8ca73f | 2014-03-24 21:41:12 +0200 | [diff] [blame] | 54 | private $serviceProcessorMap_; |
| 55 | |
| 56 | /** |
| 57 | * 'Register' a service with this <code>TMultiplexedProcessor</code>. This |
| 58 | * allows us to broker requests to individual services by using the service |
| 59 | * name to select them at request time. |
| 60 | * |
| 61 | * @param serviceName Name of a service, has to be identical to the name |
| 62 | * declared in the Thrift IDL, e.g. "WeatherReport". |
Konrad Grochowski | 3b5dacb | 2014-11-24 10:55:31 +0100 | [diff] [blame] | 63 | * @param processor Implementation of a service, usually referred to |
Jens Geyer | e8ca73f | 2014-03-24 21:41:12 +0200 | [diff] [blame] | 64 | * as "handlers", e.g. WeatherReportHandler implementing WeatherReport.Iface. |
| 65 | */ |
Roger Thomas | 6fb5923 | 2014-11-04 10:09:23 +0000 | [diff] [blame] | 66 | public function registerProcessor($serviceName, $processor) |
| 67 | { |
Jens Geyer | e8ca73f | 2014-03-24 21:41:12 +0200 | [diff] [blame] | 68 | $this->serviceProcessorMap_[$serviceName] = $processor; |
| 69 | } |
| 70 | |
| 71 | /** |
| 72 | * This implementation of <code>process</code> performs the following steps: |
| 73 | * |
| 74 | * <ol> |
| 75 | * <li>Read the beginning of the message.</li> |
| 76 | * <li>Extract the service name from the message.</li> |
| 77 | * <li>Using the service name to locate the appropriate processor.</li> |
| 78 | * <li>Dispatch to the processor, with a decorated instance of TProtocol |
| 79 | * that allows readMessageBegin() to return the original Message.</li> |
| 80 | * </ol> |
| 81 | * |
| 82 | * @throws TException If the message type is not CALL or ONEWAY, if |
Roger Thomas | 6fb5923 | 2014-11-04 10:09:23 +0000 | [diff] [blame] | 83 | * the service name was not found in the message, or if the service |
| 84 | * name was not found in the service map. |
Jens Geyer | e8ca73f | 2014-03-24 21:41:12 +0200 | [diff] [blame] | 85 | */ |
Roger Thomas | 6fb5923 | 2014-11-04 10:09:23 +0000 | [diff] [blame] | 86 | public function process(TProtocol $input, TProtocol $output) |
| 87 | { |
Jens Geyer | e8ca73f | 2014-03-24 21:41:12 +0200 | [diff] [blame] | 88 | /* |
| 89 | Use the actual underlying protocol (e.g. TBinaryProtocol) to read the |
| 90 | message header. This pulls the message "off the wire", which we'll |
| 91 | deal with at the end of this method. |
| 92 | */ |
| 93 | $input->readMessageBegin($fname, $mtype, $rseqid); |
| 94 | |
| 95 | if ($mtype !== TMessageType::CALL && $mtype != TMessageType::ONEWAY) { |
| 96 | throw new TException("This should not have happened!?"); |
| 97 | } |
| 98 | |
| 99 | // Extract the service name and the new Message name. |
| 100 | if (strpos($fname, TMultiplexedProtocol::SEPARATOR) === false) { |
| 101 | throw new TException("Service name not found in message name: {$fname}. Did you " . |
| 102 | "forget to use a TMultiplexProtocol in your client?"); |
| 103 | } |
| 104 | list($serviceName, $messageName) = explode(':', $fname, 2); |
| 105 | if (!array_key_exists($serviceName, $this->serviceProcessorMap_)) { |
| 106 | throw new TException("Service name not found: {$serviceName}. Did you forget " . |
| 107 | "to call registerProcessor()?"); |
| 108 | } |
| 109 | |
| 110 | // Dispatch processing to the stored processor |
| 111 | $processor = $this->serviceProcessorMap_[$serviceName]; |
Roger Thomas | 6fb5923 | 2014-11-04 10:09:23 +0000 | [diff] [blame] | 112 | |
Jens Geyer | e8ca73f | 2014-03-24 21:41:12 +0200 | [diff] [blame] | 113 | return $processor->process( |
Robert Lu | b03ca01 | 2018-01-18 19:06:39 +0800 | [diff] [blame] | 114 | new StoredMessageProtocol($input, $messageName, $mtype, $rseqid), |
| 115 | $output |
Jens Geyer | e8ca73f | 2014-03-24 21:41:12 +0200 | [diff] [blame] | 116 | ); |
| 117 | } |
| 118 | } |