using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net; using System.Net.Http; using System.Net.Http.Headers; using System.Security.Claims; using System.Text; using System.Threading.Tasks; using System.Web.Http; using Thermo.Active.Database.Controllers; using Thermo.Active.Listeners; using Thermo.Active.Model.DatabaseModels; using Thermo.Active.Model.DTOModels.AlarmModels; using Thermo.Active.Provider; using static Thermo.Active.Config.ServerConfig; using static Thermo.Active.Model.Constants; namespace Thermo.Active.Controllers.WebApi { [RoutePrefix("api/alarm")] public class ApiAlarmController : ApiController { [Route("paginated"), HttpPost] [WebApiAuthorize(FunctionAccess = FUNCTIONALITY_NAMES.ALARM_CMD, Action = ACTIONS.READ)] public IHttpActionResult GetDataPaginated([FromBody]DTOAlarmsFilterModel filter) { if (!ModelState.IsValid) return BadRequest(ModelState); var identity = User.Identity as ClaimsIdentity; // Find user id from the bearer token var userId = identity.Claims.FirstOrDefault(c => c.Type == USER_ID_KEY); bool canDelete = false; using (MachinesUsersController machineUserController = new MachinesUsersController()) { RoleModel role = machineUserController.GetUserRole(MachineConfig.MachineId, Convert.ToInt32(userId.Value)); canDelete = machineUserController.RoleIsAdminOrHigher(role.RoleId); } // Retrieve plc messages Dictionary plcMessages = LanguageController.GetPlcAlarmsTranslations(filter.Language) .ToDictionary( x => Convert.ToInt32(x.Key.Split('_').Last()), // This function return "alarm_id" as id, i need only the id number x => x.Value ); using (AlarmsController alarm = new AlarmsController()) { List alarms = alarm.GetPaginatedWithFilter(filter.Title, filter.Sources, filter.Page, filter.PageSize, filter.StartDate.Value, filter.EndDate, filter.UserIds, plcMessages, out int pages); return Ok(new DTOPaginatedAlarmsModel() { Alarms = alarms, Pages = pages, CanDelete = canDelete }); } } [Route("export"), HttpPost] public IHttpActionResult ExportAlarms([FromBody]DTOAlarmsFilterModel filter) { if (!ModelState.IsValid) return BadRequest(ModelState); Dictionary plcMessages = LanguageController.GetPlcAlarmsTranslations(filter.Language) .ToDictionary( x => Convert.ToInt32(x.Key.Split('_').Last()), // This function return "alarm_id" as id, i need only the id number x => x.Value ); using (AlarmsController alarm = new AlarmsController()) { // Get alarms from database List alarms = alarm.GetPaginatedWithFilter(filter.Title, filter.Sources, 0, int.MaxValue, filter.StartDate.Value, filter.EndDate, filter.UserIds, plcMessages, out int pages); Dictionary AlmPLCTras = LanguageController.GetPlcAlarmsTranslations(filter.Language); StringBuilder csv = new StringBuilder(); //string csv = ""; foreach (DTOAlarmHistoricModel model in alarms) { var alm = ""; if (model.Source == ALARM_SOURCE.PLC) alm = AlmPLCTras["alarm_" + model.AlarmId]; //csv += model.ToCsvString(alm) + Environment.NewLine; csv.Append(model.ToCsvString(alm) + Environment.NewLine); } //Parallel.ForEach(alarms, model => //{ // var alm = ""; // if (model.Source == ALARM_SOURCE.PLC) // alm = AlmPLCTras["alarm_" + model.AlarmId]; // csv.Append(model.ToCsvString(alm) + Environment.NewLine); //}); //Console.WriteLine("CSV string 2 " + st.ElapsedMilliseconds); //st.Restart(); var stream = new MemoryStream(Encoding.UTF8.GetBytes(csv.ToString()), 0, Encoding.UTF8.GetBytes(csv.ToString()).Length, false, true); var result = new HttpResponseMessage(HttpStatusCode.OK) { Content = new ByteArrayContent(stream.GetBuffer()) }; result.Content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment") { FileName = "AlarmExport.csv" }; result.Content.Headers.ContentType = new MediaTypeHeaderValue("text/csv"); return ResponseMessage(result); } } [Route("delete"), HttpDelete] public IHttpActionResult DeleteAlarms() { using (AlarmsController alarmController = new AlarmsController()) { alarmController.EmptyAlarms(); // Clean active alarms, if they are active in the next thread reading, they will be shown and stored SignalRStaticObjects.LastAlarms = new DTOAlarmsModel(); SignalRStaticObjects.AlarmDifferences = new DTOAlarmsModel(); return Ok(); } } [Route("data"), HttpPost] public IHttpActionResult GetAlarmsData(int pageSize) { using (AlarmsController alarmController = new AlarmsController()) { var alarms = alarmController.GetAlarmsData(pageSize); return Ok(alarms); } } public class DTOPaginatedAlarmsModel { public List Alarms; public int Pages; public bool CanDelete; } #region Note [Route("{alarmDescId:int}/{source:int}/note"), HttpGet] [WebApiAuthorize(FunctionAccess = FUNCTIONALITY_NAMES.ALARM_CMD, Action = ACTIONS.READ)] public IHttpActionResult GetAlarmNotes(int alarmDescId, ALARM_SOURCE source) { if (!ModelState.IsValid) return BadRequest(ModelState); using (AlarmsController alarmsController = new AlarmsController()) { // Check if alarm desc exists AlarmOccurrencesModel dbAlarm = alarmsController.FindById(alarmDescId, source); if (dbAlarm == null) return NotFound(); // Update data List notes = alarmsController.GetNotesByAlarmDescId(alarmDescId, source); return Ok(notes); } } [Route("{alarmDescId:int}/{source:int}/note"), HttpPost] [WebApiAuthorize(FunctionAccess = FUNCTIONALITY_NAMES.ALARM_CMD, Action = ACTIONS.WRITE)] public IHttpActionResult AddAlarmNote(int alarmDescId, ALARM_SOURCE source, DTONewAlarmNoteModel note) { if (!ModelState.IsValid) return BadRequest(ModelState); var identity = User.Identity as ClaimsIdentity; // Find user id from the bearer token var userId = identity.Claims.FirstOrDefault(c => c.Type == USER_ID_KEY); using (AlarmsController alarmsController = new AlarmsController()) { // Check if alarm desc exists AlarmOccurrencesModel dbAlarm = alarmsController.FindById(alarmDescId, source); if (dbAlarm == null) return NotFound(); // Update data DTOAlarmNoteModel notes = alarmsController.CreateNote(Convert.ToInt32(userId.Value), alarmDescId, source, note); return Ok(notes); } } [Route("{alarmDescId:int}/note/{noteId:int}"), HttpPut] [WebApiAuthorize(FunctionAccess = FUNCTIONALITY_NAMES.ALARM_CMD, Action = ACTIONS.WRITE)] public IHttpActionResult EditAlarmNote(int noteId, DTONewAlarmNoteModel newNote) { if (!ModelState.IsValid) return BadRequest(ModelState); var identity = User.Identity as ClaimsIdentity; // Find user id from the bearer token var userId = identity.Claims.FirstOrDefault(c => c.Type == USER_ID_KEY); using (AlarmsController alarmsController = new AlarmsController()) { // Check if alarm desc exists AlarmNoteModel dbNote = alarmsController.FindNoteById(noteId); if (dbNote == null) return NotFound(); // Check if user is different if (dbNote.UserId != Convert.ToInt32(userId.Value)) return Unauthorized(); // Update data DTOAlarmNoteModel notes = alarmsController.UpdateNote(dbNote, newNote); return Ok(notes); } } [Route("{alarmDescId:int}/note/{noteId:int}"), HttpDelete] [WebApiAuthorize(FunctionAccess = FUNCTIONALITY_NAMES.ALARM_CMD, Action = ACTIONS.WRITE)] public IHttpActionResult DeleteAlarmNote(int noteId) { if (!ModelState.IsValid) return BadRequest(ModelState); var identity = User.Identity as ClaimsIdentity; // Find user id from the bearer token var userId = identity.Claims.FirstOrDefault(c => c.Type == USER_ID_KEY); using (AlarmsController alarmsController = new AlarmsController()) { // Check if alarm desc exists AlarmNoteModel dbNote = alarmsController.FindNoteById(noteId); if (dbNote == null) return NotFound(); // Check if user is different if (dbNote.UserId != Convert.ToInt32(userId.Value)) return Unauthorized(); // Update data alarmsController.DeleteNote(dbNote.NoteId); return Ok(); } } #endregion Note #region Attachment [Route("{alarmDescId:int}/{source:int}/attachments"), HttpGet] [WebApiAuthorize(FunctionAccess = FUNCTIONALITY_NAMES.ALARM_CMD, Action = ACTIONS.READ)] public IHttpActionResult GetAttachmentsByAlarmId(int alarmDescId, ALARM_SOURCE source) { using (AlarmsController alarmsController = new AlarmsController()) { // Check if alarm desc exists AlarmOccurrencesModel dbAlarm = alarmsController.FindById(alarmDescId, source); if (dbAlarm == null) return NotFound(); List attachments = alarmsController.FindAttachmentByAlarmDescId(alarmDescId, source); return Ok(attachments); } } [Route("attachment/{attachmentId:int}"), HttpGet] public IHttpActionResult GetAttachment(int attachmentId) { using (AlarmsController alarmsController = new AlarmsController()) { // Check if attachment exist in db or physically AlarmFileModel attachment = alarmsController.FindAttachmentById(attachmentId); if (attachment == null) return NotFound(); if (!File.Exists(ALARM_ATTACHMENT_PATH + attachment.LocalFileName)) return NotFound(); return new FileResult(ALARM_ATTACHMENT_PATH + attachment.LocalFileName); } } [Route("{alarmDescId:int}/{source:int}/attachment"), HttpPost] [WebApiAuthorize(FunctionAccess = FUNCTIONALITY_NAMES.ALARM_CMD, Action = ACTIONS.WRITE)] public async Task AddAttachment(int alarmDescId, ALARM_SOURCE source) { var identity = User.Identity as ClaimsIdentity; // Find user id from the bearer token var userId = identity.Claims.FirstOrDefault(c => c.Type == USER_ID_KEY); // Check whether the POST operation is MultiPart? if (!Request.Content.IsMimeMultipartContent()) throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType); // Create CustomMultipartFormDataStreamProvider CustomMultipartFormDataStreamProvider provider = new CustomMultipartFormDataStreamProvider(ALARM_ATTACHMENT_PATH); List files = new List(); // Read all contents of multipart message into CustomMultipartFormDataStreamProvider. var result = await Request.Content.ReadAsMultipartAsync(provider); AlarmFileModel attachment = null; using (AlarmsController alarmsController = new AlarmsController()) { // Check if alarm desc exists AlarmOccurrencesModel dbAlarm = alarmsController.FindById(alarmDescId, source); if (dbAlarm == null) return NotFound(); // TODO: Remove foreach foreach (MultipartFileData file in provider.FileData) { var fileName = Path.GetFileName(file.LocalFileName); files.Add(fileName); attachment = alarmsController .AddAttachment(file.Headers.ContentDisposition.FileName.Replace("\"", string.Empty), fileName, alarmDescId, Convert.ToInt32(userId.Value), source); } } // Send OK Response along with saved file names to the client. return Ok(attachment); } [Route("attachment/{attachmentId:int}"), HttpDelete] [WebApiAuthorize(FunctionAccess = FUNCTIONALITY_NAMES.ALARM_CMD, Action = ACTIONS.WRITE)] public IHttpActionResult DeleteAttachment(int attachmentId) { var identity = User.Identity as ClaimsIdentity; // Find user id from the bearer token var userId = identity.Claims.FirstOrDefault(c => c.Type == USER_ID_KEY); using (AlarmsController alarmsController = new AlarmsController()) { // Get single file AlarmFileModel attachment = alarmsController.FindAttachmentById(attachmentId); // Check if exist in db or physically if (attachment == null) return NotFound(); // Check user if (attachment.UserId != Convert.ToInt32(userId.Value)) return Unauthorized(); alarmsController.DeleteAttachment(attachment); return Ok(); } } #endregion Attachment } }