ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/salaryman/trunk/src/smd/endpoints.rs
Revision: 14
Committed: Sat Jul 12 06:17:38 2025 UTC (2 months, 4 weeks ago) by yuzu
File size: 6384 byte(s)
Log Message:
add start, stop, restart endpoints

File Contents

# Content
1 use super::context::{SalarymanDContext, SalarymanService, ServicePath, StdinBuffer};
2 use dropshot::{HttpError, HttpResponseOk, Path, RequestContext, TypedBody, endpoint};
3 use salaryman::service::ServiceConf;
4 use std::sync::Arc;
5
6 #[endpoint {
7 method = GET,
8 path = "/service",
9 }]
10 pub async fn endpoint_get_services(
11 rqctx: RequestContext<Arc<SalarymanDContext>>,
12 ) -> Result<HttpResponseOk<Vec<ServiceConf>>, HttpError> {
13 let ret = {
14 let ctx = rqctx.context();
15 let mut v: Vec<ServiceConf> = Vec::new();
16 for i in 0..ctx.services.len() {
17 v.push(ctx.services[i].config.clone());
18 }
19 v
20 };
21 Ok(HttpResponseOk(ret))
22 }
23 #[endpoint {
24 method = GET,
25 path = "/service/{service_uuid}",
26 }]
27 pub async fn endpoint_get_service(
28 rqctx: RequestContext<Arc<SalarymanDContext>>,
29 path_params: Path<ServicePath>,
30 ) -> Result<HttpResponseOk<ServiceConf>, HttpError> {
31 let u = path_params.into_inner().service_uuid;
32 let ctx = rqctx.context();
33 let mut service: Option<Arc<SalarymanService>> = None;
34 for i in 0..ctx.services.len() {
35 if ctx.services[i].config.uuid == u {
36 service = Some(ctx.services[i].clone());
37 } else {
38 continue;
39 }
40 }
41 let s = match service {
42 Some(s) => s.config.clone(),
43 None => {
44 return Err(HttpError::for_unavail(
45 None,
46 String::from("Service Not Found"),
47 ));
48 }
49 };
50 Ok(HttpResponseOk(s))
51 }
52 #[endpoint {
53 method = GET,
54 path = "/service/{service_uuid}/start",
55 }]
56 pub async fn endpoint_start_service(
57 rqctx: RequestContext<Arc<SalarymanDContext>>,
58 path_params: Path<ServicePath>,
59 ) -> Result<HttpResponseOk<()>, HttpError> {
60 let u = path_params.into_inner().service_uuid;
61 let ctx = rqctx.context();
62 let mut service: Option<Arc<SalarymanService>> = None;
63 for i in 0..ctx.services.len() {
64 if ctx.services[i].config.uuid == u {
65 service = Some(ctx.services[i].clone());
66 } else {
67 continue;
68 }
69 }
70 match service {
71 Some(s) => {
72 let mut lock = s.service.lock().await;
73 match lock.start_with_output().await {
74 Ok(_) => (),
75 Err(e) => return Err(HttpError::for_internal_error(e.to_string())),
76 }
77 }
78 None => {
79 return Err(HttpError::for_unavail(
80 None,
81 String::from("Service Not Found"),
82 ));
83 }
84 };
85 Ok(HttpResponseOk(()))
86 }
87 #[endpoint {
88 method = GET,
89 path = "/service/{service_uuid}/stop",
90 }]
91 pub async fn endpoint_stop_service(
92 rqctx: RequestContext<Arc<SalarymanDContext>>,
93 path_params: Path<ServicePath>,
94 ) -> Result<HttpResponseOk<()>, HttpError> {
95 let u = path_params.into_inner().service_uuid;
96 let ctx = rqctx.context();
97 let mut service: Option<Arc<SalarymanService>> = None;
98 for i in 0..ctx.services.len() {
99 if ctx.services[i].config.uuid == u {
100 service = Some(ctx.services[i].clone());
101 } else {
102 continue;
103 }
104 }
105 match service {
106 Some(s) => {
107 let mut lock = s.service.lock().await;
108 match lock.stop().await {
109 Ok(_) => (),
110 Err(e) => return Err(HttpError::for_internal_error(e.to_string())),
111 }
112 }
113 None => {
114 return Err(HttpError::for_unavail(
115 None,
116 String::from("Service Not Found"),
117 ));
118 }
119 };
120 Ok(HttpResponseOk(()))
121 }
122 #[endpoint {
123 method = GET,
124 path = "/service/{service_uuid}/restart",
125 }]
126 pub async fn endpoint_restart_service(
127 rqctx: RequestContext<Arc<SalarymanDContext>>,
128 path_params: Path<ServicePath>,
129 ) -> Result<HttpResponseOk<()>, HttpError> {
130 let u = path_params.into_inner().service_uuid;
131 let ctx = rqctx.context();
132 let mut service: Option<Arc<SalarymanService>> = None;
133 for i in 0..ctx.services.len() {
134 if ctx.services[i].config.uuid == u {
135 service = Some(ctx.services[i].clone());
136 } else {
137 continue;
138 }
139 }
140 match service {
141 Some(s) => {
142 let mut lock = s.service.lock().await;
143 match lock.restart_with_output().await {
144 Ok(_) => (),
145 Err(e) => return Err(HttpError::for_internal_error(e.to_string())),
146 }
147 }
148 None => {
149 return Err(HttpError::for_unavail(
150 None,
151 String::from("Service Not Found"),
152 ));
153 }
154 };
155 Ok(HttpResponseOk(()))
156 }
157 #[endpoint {
158 method = PUT,
159 path = "/service/{service_uuid}/write"
160 }]
161 pub async fn endpoint_post_stdin(
162 rqctx: RequestContext<Arc<SalarymanDContext>>,
163 path_params: Path<ServicePath>,
164 update: TypedBody<StdinBuffer>,
165 ) -> Result<HttpResponseOk<()>, HttpError> {
166 let ctx = rqctx.context();
167 let stdin_str = update.into_inner();
168 let u = path_params.into_inner().service_uuid;
169 let mut service: Option<Arc<SalarymanService>> = None;
170 for i in 0..ctx.services.len() {
171 if ctx.services[i].config.uuid == u {
172 service = Some(ctx.services[i].clone());
173 } else {
174 continue;
175 }
176 }
177 match service {
178 Some(s) => {
179 let mut lock = s.service.lock().await;
180 if lock.started().await {
181 let b = if let Some(endl) = stdin_str.endl {
182 if endl {
183 lock.writeln_stdin(stdin_str.stdin.clone()).await //TODO: PROPERLY HANDLE ERROR!
184 } else {
185 lock.write_stdin(stdin_str.stdin.clone()).await //TODO: PROPERLY HANDLE ERROR!
186 }
187 } else {
188 lock.writeln_stdin(stdin_str.stdin.clone()).await //TODO: PROPERLY HANDLE ERROR!
189 };
190 match b {
191 Ok(_) => (),
192 Err(e) => return Err(HttpError::for_internal_error(e.to_string())),
193 }
194 }
195 drop(lock);
196 }
197 None => {
198 return Err(HttpError::for_unavail(
199 None,
200 String::from("Service Not Found"),
201 ));
202 }
203 }
204 Ok(HttpResponseOk(()))
205 }