| 188 | } |
| 189 | |
| 190 | pub async fn create(gw: Gateway) -> Result<Gateway, Error> { |
| 191 | gw.validate()?; |
| 192 | let mut c = get_async_db_conn().await?; |
| 193 | let gw: Gateway = c |
| 194 | .transaction::<Gateway, Error, _>(async |c| { |
| 195 | let query = tenant::dsl::tenant.find(&gw.tenant_id); |
| 196 | // use for_update to lock the tenant. |
| 197 | #[cfg(feature = "postgres")] |
| 198 | let query = query.for_update(); |
| 199 | let t: super::tenant::Tenant = query |
| 200 | .get_result(c) |
| 201 | .await |
| 202 | .map_err(|e| Error::from_diesel(e, gw.tenant_id.to_string()))?; |
| 203 | |
| 204 | if !t.can_have_gateways { |
| 205 | return Err(Error::NotAllowed("Tenant can not have gateways".into())); |
| 206 | } |
| 207 | |
| 208 | let gw_count: i64 = gateway::dsl::gateway |
| 209 | .select(dsl::count_star()) |
| 210 | .filter(gateway::dsl::tenant_id.eq(&gw.tenant_id)) |
| 211 | .first(c) |
| 212 | .await?; |
| 213 | |
| 214 | if t.max_gateway_count != 0 && gw_count as i32 >= t.max_gateway_count { |
| 215 | return Err(Error::NotAllowed( |
| 216 | "Max number of gateways exceeded for tenant".into(), |
| 217 | )); |
| 218 | } |
| 219 | |
| 220 | diesel::insert_into(gateway::table) |
| 221 | .values(&gw) |
| 222 | .get_result(c) |
| 223 | .await |
| 224 | .map_err(|e| Error::from_diesel(e, gw.gateway_id.to_string())) |
| 225 | }) |
| 226 | .await?; |
| 227 | info!( |
| 228 | gateway_id = %gw.gateway_id, |
| 229 | "Gateway created" |
| 230 | ); |
| 231 | Ok(gw) |
| 232 | } |
| 233 | |
| 234 | pub async fn get(gateway_id: &EUI64) -> Result<Gateway, Error> { |
| 235 | let gw = gateway::dsl::gateway |