MotionLib  1.0.0
SamBuCa motion library
AsyncAliasController.hpp
1 /*
2 ** Copyright (C) 2022 CERN
3 **
4 ** This software is provided 'as-is', without any express or implied
5 ** warranty. In no event will the authors be held liable for any damages
6 ** arising from the use of this software.
7 **
8 ** Permission is granted to anyone to use this software for any purpose,
9 ** including commercial applications, and to alter it and redistribute it
10 ** freely, subject to the following restrictions:
11 **
12 ** 1. The origin of this software must not be misrepresented; you must not
13 ** claim that you wrote the original software. If you use this software
14 ** in a product, an acknowledgment in the product documentation would be
15 ** appreciated but is not required.
16 ** 2. Altered source versions must be plainly marked as such, and must not be
17 ** misrepresented as being the original software.
18 ** 3. This notice may not be removed or altered from any source distribution.
19 **
20 ** Created on: 2022-07-31T00:08:47
21 ** Author: Sylvain Fargier <sylvain.fargier@cern.ch>
22 */
23 
24 /*
25 ** Copyright (C) 2022 CERN
26 **
27 ** This software is provided 'as-is', without any express or implied
28 ** warranty. In no event will the authors be held liable for any damages
29 ** arising from the use of this software.
30 **
31 ** Permission is granted to anyone to use this software for any purpose,
32 ** including commercial applications, and to alter it and redistribute it
33 ** freely, subject to the following restrictions:
34 **
35 ** 1. The origin of this software must not be misrepresented; you must not
36 ** claim that you wrote the original software. If you use this software
37 ** in a product, an acknowledgment in the product documentation would be
38 ** appreciated but is not required.
39 ** 2. Altered source versions must be plainly marked as such, and must not be
40 ** misrepresented as being the original software.
41 ** 3. This notice may not be removed or altered from any source distribution.
42 **
43 ** Created on: 2022-07-27T09:08:31
44 ** Author: Sylvain Fargier <sylvain.fargier@cern.ch>
45 */
46 
47 #ifndef ASYNCALIASCONTROLLER_HPP__
48 #define ASYNCALIASCONTROLLER_HPP__
49 
50 #include <algorithm>
51 #include <cmath>
52 #include <memory>
53 
54 #include <ccut/async.hpp>
55 #include <ccut/utils.hpp>
56 #include <logger/Logger.hpp>
57 #include <oatpp/core/Types.hpp>
58 #include <oatpp/core/macro/codegen.hpp>
59 #include <oatpp/core/macro/component.hpp>
60 #include <oatpp/web/server/api/ApiController.hpp>
61 
62 #include "Exception.hpp"
63 #include "FutureCoroutine.hpp"
64 #include "OatExt.hpp"
65 #include "SmcController.hpp"
66 #include "device/DeviceStore.hpp"
67 
68 #include OATPP_CODEGEN_BEGIN(ApiController)
69 
70 // clang-format off
72 {
73 public:
74  explicit AsyncAliasController(OATPP_COMPONENT(std::shared_ptr<ObjectMapper>,
75  objectMapper)) :
76  SmcController(objectMapper)
77  {
78  addTag(*this, "alias");
79  }
80 
81  ENDPOINT_INFO(getAliasList)
82  {
83  info->summary = "Get list of alias";
84  info->addResponse<List<String>>(Status::CODE_200, "application/json")
85  .addExample("example", List<String>{"alias1", "myStepper"});
86  }
87  ENDPOINT_ASYNC("GET", "/alias", getAliasList)
88  {
89  public:
90  ENDPOINT_ASYNC_INIT(getAliasList)
91  Action act() override
92  {
93  oatpp::UnorderedSet<String> ret{oatpp::UnorderedSet<String>::createShared()};
94  auto deviceStore(controller->deviceStore.lock());
95  if (deviceStore)
96  {
97  std::set<std::string> list{deviceStore->getAliasList()};
98  ret->insert(list.begin(), list.end());
99  return _return(controller->createDtoResponse(Status::CODE_200, ret));
100  }
101 
102  return _return(controller->createResponse(Status::CODE_500, "no deviceStore"));
103  }
104  };
105 
106  ENDPOINT_INFO(getAlias)
107  {
108  info->summary = "Resolve an alias";
109  info->addResponse<String>(Status::CODE_200, "application/json")
110  .addExample("example", String{"grbl://1/axis/X"});
111  info->pathParams.add<String>("id");
112  }
113  ENDPOINT_ASYNC("GET", "/alias/{id}", getAlias)
114  {
115  public:
116  ENDPOINT_ASYNC_INIT(getAlias)
117  Action act() override
118  {
119  auto deviceStore(controller->deviceStore.lock());
120  if (deviceStore)
121  {
122  const std::string id = request->getPathVariable("id").getValue("");
123  const std::string ret = deviceStore->getAlias(id);
124  if (ret.empty())
125  return _return(controller->createResponse(Status::CODE_404, "no such alias"));
126  else
127  return _return(controller->createDtoResponse(Status::CODE_200, String(ret)));
128  }
129  return _return(controller->createResponse(Status::CODE_500, "no deviceStore"));
130  }
131  };
132 
133  ENDPOINT_INFO(deleteAlias)
134  {
135  info->summary = "Delete an alias";
136  info->addResponse<String>(Status::CODE_200, "application/json");
137  info->pathParams.add<String>("id");
138  }
139  ENDPOINT_ASYNC("DELETE", "/alias/{id}", deleteAlias)
140  {
141  public:
142  ENDPOINT_ASYNC_INIT(deleteAlias)
143  Action act() override
144  {
145  auto deviceStore(controller->deviceStore.lock());
146  if (deviceStore)
147  {
148  const std::string id = request->getPathVariable("id").getValue("");
149  deviceStore->removeAlias(id);
150  return _return(controller->createResponse(Status::CODE_200, "done"));
151  }
152  return _return(controller->createResponse(Status::CODE_500, "no deviceStore"));
153  }
154  };
155 
156  ENDPOINT_INFO(putAlias)
157  {
158  info->summary = "Create or update an alias";
159  info->addResponse<String>(Status::CODE_200, "application/json");
160  info->pathParams.add<String>("id");
161  info->addConsumes<String>("application/json")
162  .addExample("device id", String("grbl://1/axis/X"));
163  }
164  ENDPOINT_ASYNC("PUT", "/alias/{id}", putAlias)
165  {
166  public:
167  ENDPOINT_ASYNC_INIT(putAlias)
168  Action act() override
169  {
170  return request
171  ->readBodyToDtoAsync<String>(
172  controller->getDefaultObjectMapper())
173  .callbackTo(&putAlias::onBodyReady);
174  }
175  Action onBodyReady(const String &target)
176  {
177  auto deviceStore(controller->deviceStore.lock());
178  if (deviceStore)
179  {
180  const std::string id = request->getPathVariable("id").getValue("");
181  deviceStore->addAlias(id, target.getValue(""));
182  return _return(controller->createResponse(Status::CODE_200, "done"));
183  }
184  return _return(controller->createResponse(Status::CODE_500, "no deviceStore"));
185  }
186  };
187 };
188 
189 //clang-format on
190 
191 #include OATPP_CODEGEN_END(ApiController)
192 
193 #endif