blob: 4c66cb894d5429aa228708e319e75e64b93ef1ae [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>
cyyca8af9b2019-01-11 22:13:12 +080021#include <thrift/concurrency/ThreadFactory.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>
Ben Craig74086f12015-07-04 17:18:58 -050030
Mark Slee07a3aab2007-03-07 05:45:10 +000031#include <iostream>
32#include <stdexcept>
33#include <sstream>
34
35#include "../gen-cpp/Calculator.h"
36
37using namespace std;
T Jake Lucianib5e62212009-01-31 22:36:20 +000038using namespace apache::thrift;
Jens Geyer04a4c152014-10-14 21:30:28 +020039using namespace apache::thrift::concurrency;
T Jake Lucianib5e62212009-01-31 22:36:20 +000040using namespace apache::thrift::protocol;
41using namespace apache::thrift::transport;
42using namespace apache::thrift::server;
Mark Slee07a3aab2007-03-07 05:45:10 +000043
44using namespace tutorial;
45using namespace shared;
46
Mark Slee07a3aab2007-03-07 05:45:10 +000047class CalculatorHandler : public CalculatorIf {
Konrad Grochowski16a23a62014-11-13 15:33:38 +010048public:
Sebastian Zenker042580f2019-01-29 15:48:12 +010049 CalculatorHandler() = default;
Mark Slee07a3aab2007-03-07 05:45:10 +000050
CJCombrink4a280d52024-03-14 19:57:41 +010051 void ping() override { cout << "ping()" << '\n'; }
Mark Slee07a3aab2007-03-07 05:45:10 +000052
Sebastian Zenker042580f2019-01-29 15:48:12 +010053 int32_t add(const int32_t n1, const int32_t n2) override {
CJCombrink4a280d52024-03-14 19:57:41 +010054 cout << "add(" << n1 << ", " << n2 << ")" << '\n';
Mark Slee07a3aab2007-03-07 05:45:10 +000055 return n1 + n2;
56 }
57
Sebastian Zenker042580f2019-01-29 15:48:12 +010058 int32_t calculate(const int32_t logid, const Work& work) override {
CJCombrink4a280d52024-03-14 19:57:41 +010059 cout << "calculate(" << logid << ", " << work << ")" << '\n';
Mark Slee07a3aab2007-03-07 05:45:10 +000060 int32_t val;
61
62 switch (work.op) {
Bryan Duxbury833ae492010-09-27 17:26:02 +000063 case Operation::ADD:
Mark Slee07a3aab2007-03-07 05:45:10 +000064 val = work.num1 + work.num2;
65 break;
Bryan Duxbury833ae492010-09-27 17:26:02 +000066 case Operation::SUBTRACT:
Mark Slee07a3aab2007-03-07 05:45:10 +000067 val = work.num1 - work.num2;
68 break;
Bryan Duxbury833ae492010-09-27 17:26:02 +000069 case Operation::MULTIPLY:
Mark Slee07a3aab2007-03-07 05:45:10 +000070 val = work.num1 * work.num2;
71 break;
Bryan Duxbury833ae492010-09-27 17:26:02 +000072 case Operation::DIVIDE:
Mark Slee07a3aab2007-03-07 05:45:10 +000073 if (work.num2 == 0) {
74 InvalidOperation io;
Konrad Grochowski3b115df2015-05-18 17:58:36 +020075 io.whatOp = work.op;
Mark Slee07a3aab2007-03-07 05:45:10 +000076 io.why = "Cannot divide by 0";
77 throw io;
78 }
79 val = work.num1 / work.num2;
80 break;
81 default:
82 InvalidOperation io;
Konrad Grochowski3b115df2015-05-18 17:58:36 +020083 io.whatOp = work.op;
Mark Slee07a3aab2007-03-07 05:45:10 +000084 io.why = "Invalid Operation";
85 throw io;
86 }
87
88 SharedStruct ss;
89 ss.key = logid;
Konrad Grochowskia8eec712014-09-04 00:56:27 +020090 ss.value = to_string(val);
Mark Slee07a3aab2007-03-07 05:45:10 +000091
92 log[logid] = ss;
93
94 return val;
95 }
96
Sebastian Zenker042580f2019-01-29 15:48:12 +010097 void getStruct(SharedStruct& ret, const int32_t logid) override {
CJCombrink4a280d52024-03-14 19:57:41 +010098 cout << "getStruct(" << logid << ")" << '\n';
Mark Slee07a3aab2007-03-07 05:45:10 +000099 ret = log[logid];
100 }
101
CJCombrink4a280d52024-03-14 19:57:41 +0100102 void zip() override { cout << "zip()" << '\n'; }
Mark Slee07a3aab2007-03-07 05:45:10 +0000103
104protected:
105 map<int32_t, SharedStruct> log;
Mark Slee07a3aab2007-03-07 05:45:10 +0000106};
107
Ben Craig74086f12015-07-04 17:18:58 -0500108/*
109 CalculatorIfFactory is code generated.
110 CalculatorCloneFactory is useful for getting access to the server side of the
111 transport. It is also useful for making per-connection state. Without this
112 CloneFactory, all connections will end up sharing the same handler instance.
113*/
114class CalculatorCloneFactory : virtual public CalculatorIfFactory {
115 public:
Sebastian Zenker042580f2019-01-29 15:48:12 +0100116 ~CalculatorCloneFactory() override = default;
117 CalculatorIf* getHandler(const ::apache::thrift::TConnectionInfo& connInfo) override
Ben Craig74086f12015-07-04 17:18:58 -0500118 {
cyy316723a2019-01-05 16:35:14 +0800119 std::shared_ptr<TSocket> sock = std::dynamic_pointer_cast<TSocket>(connInfo.transport);
Ben Craig74086f12015-07-04 17:18:58 -0500120 cout << "Incoming connection\n";
121 cout << "\tSocketInfo: " << sock->getSocketInfo() << "\n";
122 cout << "\tPeerHost: " << sock->getPeerHost() << "\n";
123 cout << "\tPeerAddress: " << sock->getPeerAddress() << "\n";
124 cout << "\tPeerPort: " << sock->getPeerPort() << "\n";
125 return new CalculatorHandler;
126 }
Sebastian Zenker042580f2019-01-29 15:48:12 +0100127 void releaseHandler( ::shared::SharedServiceIf* handler) override {
Ben Craig74086f12015-07-04 17:18:58 -0500128 delete handler;
129 }
130};
Mark Slee07a3aab2007-03-07 05:45:10 +0000131
Ben Craig74086f12015-07-04 17:18:58 -0500132int main() {
133 TThreadedServer server(
cyy316723a2019-01-05 16:35:14 +0800134 std::make_shared<CalculatorProcessorFactory>(std::make_shared<CalculatorCloneFactory>()),
135 std::make_shared<TServerSocket>(9090), //port
136 std::make_shared<TBufferedTransportFactory>(),
137 std::make_shared<TBinaryProtocolFactory>());
Ben Craig74086f12015-07-04 17:18:58 -0500138
139 /*
140 // if you don't need per-connection state, do the following instead
141 TThreadedServer server(
cyy316723a2019-01-05 16:35:14 +0800142 std::make_shared<CalculatorProcessor>(std::make_shared<CalculatorHandler>()),
143 std::make_shared<TServerSocket>(9090), //port
144 std::make_shared<TBufferedTransportFactory>(),
145 std::make_shared<TBinaryProtocolFactory>());
Ben Craig74086f12015-07-04 17:18:58 -0500146 */
Mark Slee07a3aab2007-03-07 05:45:10 +0000147
148 /**
Ben Craig74086f12015-07-04 17:18:58 -0500149 * Here are some alternate server types...
150
151 // This server only allows one connection at a time, but spawns no threads
152 TSimpleServer server(
cyy316723a2019-01-05 16:35:14 +0800153 std::make_shared<CalculatorProcessor>(std::make_shared<CalculatorHandler>()),
154 std::make_shared<TServerSocket>(9090),
155 std::make_shared<TBufferedTransportFactory>(),
156 std::make_shared<TBinaryProtocolFactory>());
Mark Slee07a3aab2007-03-07 05:45:10 +0000157
Jens Geyer04a4c152014-10-14 21:30:28 +0200158 const int workerCount = 4;
159
cyy316723a2019-01-05 16:35:14 +0800160 std::shared_ptr<ThreadManager> threadManager =
Mark Slee07a3aab2007-03-07 05:45:10 +0000161 ThreadManager::newSimpleThreadManager(workerCount);
Ben Craig74086f12015-07-04 17:18:58 -0500162 threadManager->threadFactory(
cyyca8af9b2019-01-11 22:13:12 +0800163 std::make_shared<ThreadFactory>());
Mark Slee07a3aab2007-03-07 05:45:10 +0000164 threadManager->start();
Mark Slee07a3aab2007-03-07 05:45:10 +0000165
Ben Craig74086f12015-07-04 17:18:58 -0500166 // This server allows "workerCount" connection at a time, and reuses threads
167 TThreadPoolServer server(
cyy316723a2019-01-05 16:35:14 +0800168 std::make_shared<CalculatorProcessorFactory>(std::make_shared<CalculatorCloneFactory>()),
169 std::make_shared<TServerSocket>(9090),
170 std::make_shared<TBufferedTransportFactory>(),
171 std::make_shared<TBinaryProtocolFactory>(),
Ben Craig74086f12015-07-04 17:18:58 -0500172 threadManager);
Mark Slee07a3aab2007-03-07 05:45:10 +0000173 */
174
CJCombrink4a280d52024-03-14 19:57:41 +0100175 cout << "Starting the server..." << '\n';
Mark Slee07a3aab2007-03-07 05:45:10 +0000176 server.serve();
CJCombrink4a280d52024-03-14 19:57:41 +0100177 cout << "Done." << '\n';
Mark Slee07a3aab2007-03-07 05:45:10 +0000178 return 0;
179}