blob: eafffa973e63f46659440214b8548c0cfc16649f [file] [log] [blame]
David Reissea2cba82009-03-30 21:35:00 +00001/*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. 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,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19
Roger Meier49ff8b12012-04-13 09:12:31 +000020#include <thrift/concurrency/ThreadManager.h>
Ben Craig74086f12015-07-04 17:18:58 -050021#include <thrift/concurrency/PlatformThreadFactory.h>
Roger Meier49ff8b12012-04-13 09:12:31 +000022#include <thrift/protocol/TBinaryProtocol.h>
23#include <thrift/server/TSimpleServer.h>
24#include <thrift/server/TThreadPoolServer.h>
25#include <thrift/server/TThreadedServer.h>
26#include <thrift/transport/TServerSocket.h>
Ben Craig74086f12015-07-04 17:18:58 -050027#include <thrift/transport/TSocket.h>
Roger Meier49ff8b12012-04-13 09:12:31 +000028#include <thrift/transport/TTransportUtils.h>
Konrad Grochowskia8eec712014-09-04 00:56:27 +020029#include <thrift/TToString.h>
Mark Slee07a3aab2007-03-07 05:45:10 +000030
Ben Craig74086f12015-07-04 17:18:58 -050031#include <boost/make_shared.hpp>
32
Mark Slee07a3aab2007-03-07 05:45:10 +000033#include <iostream>
34#include <stdexcept>
35#include <sstream>
36
37#include "../gen-cpp/Calculator.h"
38
39using namespace std;
T Jake Lucianib5e62212009-01-31 22:36:20 +000040using namespace apache::thrift;
Jens Geyer04a4c152014-10-14 21:30:28 +020041using namespace apache::thrift::concurrency;
T Jake Lucianib5e62212009-01-31 22:36:20 +000042using namespace apache::thrift::protocol;
43using namespace apache::thrift::transport;
44using namespace apache::thrift::server;
Mark Slee07a3aab2007-03-07 05:45:10 +000045
46using namespace tutorial;
47using namespace shared;
48
Mark Slee07a3aab2007-03-07 05:45:10 +000049class CalculatorHandler : public CalculatorIf {
Konrad Grochowski16a23a62014-11-13 15:33:38 +010050public:
Mark Slee07a3aab2007-03-07 05:45:10 +000051 CalculatorHandler() {}
52
Konrad Grochowski16a23a62014-11-13 15:33:38 +010053 void ping() { cout << "ping()" << endl; }
Mark Slee07a3aab2007-03-07 05:45:10 +000054
55 int32_t add(const int32_t n1, const int32_t n2) {
Konrad Grochowskia8eec712014-09-04 00:56:27 +020056 cout << "add(" << n1 << ", " << n2 << ")" << endl;
Mark Slee07a3aab2007-03-07 05:45:10 +000057 return n1 + n2;
58 }
59
Konrad Grochowskia8eec712014-09-04 00:56:27 +020060 int32_t calculate(const int32_t logid, const Work& work) {
61 cout << "calculate(" << logid << ", " << work << ")" << endl;
Mark Slee07a3aab2007-03-07 05:45:10 +000062 int32_t val;
63
64 switch (work.op) {
Bryan Duxbury833ae492010-09-27 17:26:02 +000065 case Operation::ADD:
Mark Slee07a3aab2007-03-07 05:45:10 +000066 val = work.num1 + work.num2;
67 break;
Bryan Duxbury833ae492010-09-27 17:26:02 +000068 case Operation::SUBTRACT:
Mark Slee07a3aab2007-03-07 05:45:10 +000069 val = work.num1 - work.num2;
70 break;
Bryan Duxbury833ae492010-09-27 17:26:02 +000071 case Operation::MULTIPLY:
Mark Slee07a3aab2007-03-07 05:45:10 +000072 val = work.num1 * work.num2;
73 break;
Bryan Duxbury833ae492010-09-27 17:26:02 +000074 case Operation::DIVIDE:
Mark Slee07a3aab2007-03-07 05:45:10 +000075 if (work.num2 == 0) {
76 InvalidOperation io;
Konrad Grochowski3b115df2015-05-18 17:58:36 +020077 io.whatOp = work.op;
Mark Slee07a3aab2007-03-07 05:45:10 +000078 io.why = "Cannot divide by 0";
79 throw io;
80 }
81 val = work.num1 / work.num2;
82 break;
83 default:
84 InvalidOperation io;
Konrad Grochowski3b115df2015-05-18 17:58:36 +020085 io.whatOp = work.op;
Mark Slee07a3aab2007-03-07 05:45:10 +000086 io.why = "Invalid Operation";
87 throw io;
88 }
89
90 SharedStruct ss;
91 ss.key = logid;
Konrad Grochowskia8eec712014-09-04 00:56:27 +020092 ss.value = to_string(val);
Mark Slee07a3aab2007-03-07 05:45:10 +000093
94 log[logid] = ss;
95
96 return val;
97 }
98
Konrad Grochowski16a23a62014-11-13 15:33:38 +010099 void getStruct(SharedStruct& ret, const int32_t logid) {
Konrad Grochowskia8eec712014-09-04 00:56:27 +0200100 cout << "getStruct(" << logid << ")" << endl;
Mark Slee07a3aab2007-03-07 05:45:10 +0000101 ret = log[logid];
102 }
103
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100104 void zip() { cout << "zip()" << endl; }
Mark Slee07a3aab2007-03-07 05:45:10 +0000105
106protected:
107 map<int32_t, SharedStruct> log;
Mark Slee07a3aab2007-03-07 05:45:10 +0000108};
109
Ben Craig74086f12015-07-04 17:18:58 -0500110/*
111 CalculatorIfFactory is code generated.
112 CalculatorCloneFactory is useful for getting access to the server side of the
113 transport. It is also useful for making per-connection state. Without this
114 CloneFactory, all connections will end up sharing the same handler instance.
115*/
116class CalculatorCloneFactory : virtual public CalculatorIfFactory {
117 public:
118 virtual ~CalculatorCloneFactory() {}
119 virtual CalculatorIf* getHandler(const ::apache::thrift::TConnectionInfo& connInfo)
120 {
121 boost::shared_ptr<TSocket> sock = boost::dynamic_pointer_cast<TSocket>(connInfo.transport);
122 cout << "Incoming connection\n";
123 cout << "\tSocketInfo: " << sock->getSocketInfo() << "\n";
124 cout << "\tPeerHost: " << sock->getPeerHost() << "\n";
125 cout << "\tPeerAddress: " << sock->getPeerAddress() << "\n";
126 cout << "\tPeerPort: " << sock->getPeerPort() << "\n";
127 return new CalculatorHandler;
128 }
129 virtual void releaseHandler( ::shared::SharedServiceIf* handler) {
130 delete handler;
131 }
132};
Mark Slee07a3aab2007-03-07 05:45:10 +0000133
Ben Craig74086f12015-07-04 17:18:58 -0500134int main() {
135 TThreadedServer server(
136 boost::make_shared<CalculatorProcessorFactory>(boost::make_shared<CalculatorCloneFactory>()),
137 boost::make_shared<TServerSocket>(9090), //port
138 boost::make_shared<TBufferedTransportFactory>(),
139 boost::make_shared<TBinaryProtocolFactory>());
140
141 /*
142 // if you don't need per-connection state, do the following instead
143 TThreadedServer server(
144 boost::make_shared<CalculatorProcessor>(boost::make_shared<CalculatorHandler>()),
145 boost::make_shared<TServerSocket>(9090), //port
146 boost::make_shared<TBufferedTransportFactory>(),
147 boost::make_shared<TBinaryProtocolFactory>());
148 */
Mark Slee07a3aab2007-03-07 05:45:10 +0000149
150 /**
Ben Craig74086f12015-07-04 17:18:58 -0500151 * Here are some alternate server types...
152
153 // This server only allows one connection at a time, but spawns no threads
154 TSimpleServer server(
155 boost::make_shared<CalculatorProcessor>(boost::make_shared<CalculatorHandler>()),
156 boost::make_shared<TServerSocket>(9090),
157 boost::make_shared<TBufferedTransportFactory>(),
158 boost::make_shared<TBinaryProtocolFactory>());
Mark Slee07a3aab2007-03-07 05:45:10 +0000159
Jens Geyer04a4c152014-10-14 21:30:28 +0200160 const int workerCount = 4;
161
Roger Meier5f2d34e2013-11-16 16:43:41 +0100162 boost::shared_ptr<ThreadManager> threadManager =
Mark Slee07a3aab2007-03-07 05:45:10 +0000163 ThreadManager::newSimpleThreadManager(workerCount);
Ben Craig74086f12015-07-04 17:18:58 -0500164 threadManager->threadFactory(
165 boost::make_shared<PlatformThreadFactory>());
Mark Slee07a3aab2007-03-07 05:45:10 +0000166 threadManager->start();
Mark Slee07a3aab2007-03-07 05:45:10 +0000167
Ben Craig74086f12015-07-04 17:18:58 -0500168 // This server allows "workerCount" connection at a time, and reuses threads
169 TThreadPoolServer server(
170 boost::make_shared<CalculatorProcessorFactory>(boost::make_shared<CalculatorCloneFactory>()),
171 boost::make_shared<TServerSocket>(9090),
172 boost::make_shared<TBufferedTransportFactory>(),
173 boost::make_shared<TBinaryProtocolFactory>(),
174 threadManager);
Mark Slee07a3aab2007-03-07 05:45:10 +0000175 */
176
Konrad Grochowskia8eec712014-09-04 00:56:27 +0200177 cout << "Starting the server..." << endl;
Mark Slee07a3aab2007-03-07 05:45:10 +0000178 server.serve();
Konrad Grochowskia8eec712014-09-04 00:56:27 +0200179 cout << "Done." << endl;
Mark Slee07a3aab2007-03-07 05:45:10 +0000180 return 0;
181}