identt
HrpcRemoteEndpointService.hpp
Go to the documentation of this file.
1 
33 #ifndef _IDENTT_HRPC_REMOTE_ENDPOINT_SERVICE_HPP_
34 #define _IDENTT_HRPC_REMOTE_ENDPOINT_SERVICE_HPP_
35 
36 #include "query/QueryBase.hpp"
38 #include "store/StoreTrans.hpp"
39 
40 #include "hrpc/RemoteKeeper.hpp"
41 #include "hrpc/HrpcClient.hpp"
42 
43 namespace identt {
44 namespace hrpc {
45 
46 template <class HttpServerT>
48  public identt::query::ServiceBase<HttpServerT>,
49  protected identt::hrpc::ProtoServiceBase<HttpServerT> {
50 public:
51 
72  identt::utils::SharedTable::pointer stptr,
73  typename std::shared_ptr<HttpServerT> server,
74  ::identt::hrpc::RemoteKeeper::pointer rkeeper,
75  unsigned int scope)
76  :
77  identt::query::ServiceBase<HttpServerT>(IDENTT_SERVICE_SCOPE_HTTP | IDENTT_SERVICE_SCOPE_HTTPS)
78  {
79  if (!(this->myscope & scope)) return; // scope mismatch
80 
81  // Endpoint : POST _identt/identity/remote/v1/endpoint
82 
83  server->resource["/_identt/identity/remote/v1/endpoint$"]["POST"]
84  =[this,stptr,rkeeper](typename HttpServerT::RespPtr response, typename HttpServerT::ReqPtr request) {
85  IDENTT_PARALLEL_ONE([this,stptr,rkeeper,response,request] {
86  std::string output;
87  int ecode=M_UNKNOWN;
88  try
89  {
90  if (!this->ProtoRequest(request))
91  throw identt::BadDataException("Only Protobuf Supported");
92  if (!this->SharedSecretOK(request,stptr->shared_secret.Get()))
93  throw identt::BadDataException("Bad Shared Secret");
94 
95  auto sname = this->ServiceName(request);
96 
97  if (!stptr->is_ready.Get()) throw identt::BadDataException("System Not Ready");
98 
99  // start here
100  switch(sname) {
101  case ::identt::hrpc::R_REGISTER : {
102  identt::hrpc::StateT data;
103  if (!data.ParseFromString( b64_decode(request->content.string()) ))
104  throw identt::BadDataException("Bad Protobuf Format");
105  // action
106  // update remote in list
107  if (stptr->is_master.Get()) {
108  rkeeper->AddHost( data.thisurl(), data.logcounter(), data.ts() );
109  rkeeper->HostUpdate();
110  }
111  // aftermath
112  data.Clear();
113  rkeeper->GetHosts(&data);
114  data.SerializeToString(&output);
115  DLOG(INFO) << request->path << " " << sname;
116  break;
117  }
118  case ::identt::hrpc::R_READONE : {
119  identt::store::TransactionT data;
120  if (!data.ParseFromString( b64_decode(request->content.string()) ))
121  throw identt::BadDataException("Bad Protobuf Format");
122  // action
123  identt::store::StoreTrans service; //ReadOne
124  service.ReadOne(stptr, &data);
125  // aftermath
126  data.SerializeToString(&output);
127  DLOG(INFO) << request->path << " " << sname;
128  break;
129  }
130  case ::identt::hrpc::R_TRANSLOG : {
131  identt::store::TransListT data;
132  if (!data.ParseFromString( b64_decode(request->content.string()) ))
133  throw identt::BadDataException("Bad Protobuf Format");
134  // action
135  // check if counter is current
136  auto logc = stptr->logcounter.Get();
137  if (data.lastid()>logc)
138  throw ::identt::BadDataException("Remote Log Counter ahead");
139  // if no change return
140  if (data.lastid()==logc) {
141  data.set_ts( IDENTT_CURRTIME_MS );
142  data.set_currid( logc );
143  data.set_limit( 0 );
144  // set the last slave as this if unset, this slave is in sync
145  // so future pushes can go to this
146  if (stptr->lastslave.Get().empty())
147  stptr->lastslave.Set(data.endpoint());
148  }
149  else {
150  // if counter is not current
151  identt::store::StoreTrans service; //ReadLog
152  service.ReadLog(stptr, &data);
153  }
154  // aftermath
155  data.SerializeToString(&output);
156  DLOG(INFO) << request->path << " " << sname;
157  break;
158  }
159  case ::identt::hrpc::R_SETINFO : {
160  identt::hrpc::StateT data;
161  if (!data.ParseFromString( b64_decode(request->content.string()) ))
162  throw identt::BadDataException("Bad Protobuf Format");
163  // action
164  // update remotes only if from master
165  rkeeper->SetHosts(&data);
166  // aftermath
167  data.Clear();
168  rkeeper->GetHosts(&data);
169  data.SerializeToString(&output);
170  DLOG(INFO) << request->path << " " << sname;
171  break;
172  }
173  case ::identt::hrpc::R_ADDHOST : {
174  identt::hrpc::RemoteT data;
175  if (!data.ParseFromString( b64_decode(request->content.string()) ))
176  throw identt::BadDataException("Bad Protobuf Format");
177  // action
178  // update remotes only if from master
179  if (stptr->is_master.Get())
180  throw identt::BadDataException("Host addition is slave only");
181  rkeeper->AddHost(&data);
182  // aftermath
183  data.Clear();
184  data.SerializeToString(&output);
185  DLOG(INFO) << request->path << " " << sname;
186  break;
187  }
188  case ::identt::hrpc::R_BUFFTRANS : {
189  identt::store::TransactionT data;
190  if (!data.ParseFromString( b64_decode(request->content.string()) ))
191  throw identt::BadDataException("Bad Protobuf Format");
192  // update only if from master
193  if (stptr->is_master.Get())
194  throw identt::BadDataException("Data addition is slave only");
195  // action
196  data.SerializeToString(&output);
197  stptr->transactions.AddOne(data.id(),output);
198  // aftermath
199  DLOG(INFO) << request->path << " " << sname;
200  break;
201  }
202  default:
203  DLOG(INFO) << request->path << " " << sname;
204  throw identt::BadDataException("Service Name unknown or unimplemented");
205  break;
206  }
207  ecode=0; // something reached here
208  // end here
209 
210  }
211  catch (...)
212  {
213  ecode=M_UNKNOWN; // default
214  output="Unknown Error";
215  }
216 
217  if (ecode==0)
218  {
219  this->ServiceOKAction(response,request,b64_encode(output));
220  }
221  else
222  {
223  this->ServiceErrAction(response,request,ecode,output);
224  }
225  });
226  };
227  }
228 };
229 } // namespace query
230 } // namespace identt
231 
232 #endif // _IDENTT_HRPC_REMOTE_ENDPOINT_SERVICE_HPP_
233 
ServiceBase(const unsigned int myscope_)
Constructor : to be used by inherited classes.
Definition: ServiceBase.hpp:65
void ServiceOKAction(typename HttpServerT::RespPtr response, typename HttpServerT::ReqPtr request, std::string &payload)
ServiceOKAction : OK Action template for service.
Definition: ProtoServiceBase.hpp:114
int ServiceName(typename HttpServerT::ReqPtr request)
ServiceName : Check protobuf request service name.
Definition: ProtoServiceBase.hpp:93
HrpcRemoteEndpointService(identt::utils::SharedTable::pointer stptr, typename std::shared_ptr< HttpServerT > server, ::identt::hrpc::RemoteKeeper::pointer rkeeper, unsigned int scope)
HrpcRemoteEndpointService : constructor.
Definition: HrpcRemoteEndpointService.hpp:71
void ReadOne(::identt::utils::SharedTable::pointer stptr, TransactionT *trans)
ReadOne : read a single transaction.
Definition: StoreTrans.cc:144
Definition: ServiceBase.hpp:55
Definition: CryptoBase.hpp:49
Definition: BaseUtils.hpp:89
void ReadLog(::identt::utils::SharedTable::pointer stptr, TransListT *tlist)
ReadLog : read from log in sequence.
bool SharedSecretOK(typename HttpServerT::ReqPtr request, std::string sharedkey)
SharedSecretOK : Check if shared key header is present and ok.
Definition: ProtoServiceBase.hpp:77
void ServiceErrAction(typename HttpServerT::RespPtr response, typename HttpServerT::ReqPtr request, int ecode, std::string &emsg)
ServiceErrAction : Error Action template for service.
Definition: ProtoServiceBase.hpp:173
Definition: ProtoServiceBase.hpp:43
Definition: StoreTrans.hpp:41
bool ProtoRequest(typename HttpServerT::ReqPtr request)
ProtoRequest : Check if request is protobuf from Content-Type and Accept fields.
Definition: ProtoServiceBase.hpp:55
Definition: HrpcRemoteEndpointService.hpp:47