public async Task AddActionAsync(Trigger trigger, TriggerAction action, CancellationToken ct = default) { using var builder = StoredProcedureBuilder.Create(this.m_ctx.Connection); builder.WithParameter("triggerid", trigger.ID, NpgsqlDbType.Bigint); builder.WithParameter("channel", (int)action.Channel, NpgsqlDbType.Integer); builder.WithParameter("target", action.Target, NpgsqlDbType.Varchar); builder.WithParameter("message", action.Message, NpgsqlDbType.Text); builder.WithFunction(NetworkApi_CreateAction); try { var reader = await builder.ExecuteAsync(ct).ConfigureAwait(false); if (await reader.ReadAsync(ct).ConfigureAwait(false)) { action.ID = reader.GetInt64(0); } await reader.DisposeAsync().ConfigureAwait(false); } catch (PostgresException exception) { if (exception.SqlState == PostgresErrorCodes.UniqueViolation) { throw new FormatException("Trigger action for this channel already exists!"); } } }
public async Task <IActionResult> AddAction(long triggerId, [FromBody] TriggerAction action) { var invalidResponse = new Response <string>(); if (action == null) { invalidResponse.AddError("No actions provided to add."); return(this.UnprocessableEntity(invalidResponse)); } if (action.Channel > TriggerChannel.MQTT && string.IsNullOrEmpty(action.Target)) { invalidResponse.AddError("Missing target attribute."); return(this.UnprocessableEntity(invalidResponse)); } var trigger = await this.m_triggers.GetAsync(triggerId).ConfigureAwait(false); action.TriggerID = triggerId; if (trigger == null) { return(this.NotFound()); } var authForTrigger = await this.AuthenticateUserForSensor(trigger.SensorID).ConfigureAwait(false); var error = new Response <string>(); if (action.Channel > TriggerChannel.MQTT) { authForTrigger = await this.CreatedTargetedActionAsync(action, error).ConfigureAwait(false); } if (!authForTrigger) { return(this.UnprocessableEntity(error)); } try { await this.m_triggers.AddActionAsync(trigger, action).ConfigureAwait(false); await this.m_mqtt.PublishCommandAsync(CommandType.AddSensor, trigger.SensorID).ConfigureAwait(false); } catch (FormatException ex) { var response = new Response <string>(); response.AddError(ex.Message); return(this.UnprocessableEntity(response)); } trigger.TriggerActions ??= new List <TriggerAction>(); trigger.TriggerActions.Add(action); return(this.CreatedAtAction(nameof(this.GetById), new { triggerId = trigger.ID }, new Response <Trigger>(trigger))); }
private static async Task <bool> GetTriggerFromReaderAsync(Trigger trigger, DbDataReader reader, CancellationToken ct) { var id = reader.GetInt64(0); trigger.ID = id; trigger.SensorID = reader.GetString(1); trigger.KeyValue = reader.GetString(2); trigger.LowerEdge = SafeGetValue <double?>(reader, 3); trigger.UpperEdge = SafeGetValue <double?>(reader, 4); trigger.FormalLanguage = SafeGetValue <string>(reader, 5); trigger.Type = (TriggerType)reader.GetInt32(6); do { id = reader.GetInt64(0); if (trigger.ID != id) { return(false); } if (await reader.IsDBNullAsync(7, ct)) { var hasNext = await reader.ReadAsync(ct).ConfigureAwait(false); return(!hasNext); } var action = new TriggerAction { ID = reader.GetInt64(7), Channel = (TriggerChannel)reader.GetInt32(8), Target = SafeGetValue <string>(reader, 9), Message = reader.GetString(10), TriggerID = id }; trigger.TriggerActions ??= new List <TriggerAction>(); trigger.TriggerActions.Add(action); } while(await reader.ReadAsync(ct)); return(true); }
private async Task <bool> CreatedTargetedActionAsync(TriggerAction action, Response <string> response) { bool auth; if (action.Target == null) { return(false); } if (action.Channel == TriggerChannel.ControlMessage) { var actuator = await this.m_sensors.GetAsync(action.Target).ConfigureAwait(false); if (actuator == null) { return(false); } auth = await this.AuthenticateUserForSensor(actuator, false).ConfigureAwait(false); if (!auth) { response.AddError("Unable to authorize target sensor/actuator!"); } } else { auth = Uri.TryCreate(action.Target, UriKind.Absolute, out var result) && result.Scheme == Uri.UriSchemeHttp || result?.Scheme == Uri.UriSchemeHttps; if (!auth) { response.AddError("Invalid URL in target field."); } } return(auth); }