Files
Samuele E. Locatelli 239758e9d9 Update output log
2019-12-12 16:02:17 +01:00

292 lines
9.4 KiB
C#

using Newtonsoft.Json;
using SteamWare;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text.RegularExpressions;
namespace WebLCP.WUC
{
public partial class mod_startJob : BaseUserControl
{
public Dictionary<string, string> errorList
{
get
{
Dictionary<string, string> answ = new Dictionary<string, string>();
string rawData = memLayer.ML.StringSessionObj("errorList");
if (!string.IsNullOrEmpty(rawData))
{
answ = JsonConvert.DeserializeObject<Dictionary<string, string>>(rawData);
}
return answ;
}
set
{
string jsonData = JsonConvert.SerializeObject(value);
memLayer.ML.setSessionVal("errorList", jsonData);
}
}
public Dictionary<string, string> successList
{
get
{
Dictionary<string, string> answ = new Dictionary<string, string>();
string rawData = memLayer.ML.StringSessionObj("successList");
if (!string.IsNullOrEmpty(rawData))
{
answ = JsonConvert.DeserializeObject<Dictionary<string, string>>(rawData);
}
return answ;
}
set
{
string jsonData = JsonConvert.SerializeObject(value);
memLayer.ML.setSessionVal("successList", jsonData);
}
}
protected void Page_Load(object sender, EventArgs e)
{
if (devicesAuthProxy.stObj.utente == "")
{
Response.Redirect("Default");
}
dataLayer.man.cleanupTempDir();
dataLayer.man.checkJobs();
if (!Page.IsPostBack)
{
dataLayer.man.cleanupJobsDir();
}
}
protected void lbtUpload_Click(object sender, EventArgs e)
{
if (devicesAuthProxy.stObj.utente != "")
{
checkAndUploadFile();
// ricarico x evitare problemi di file già "in pancia"
//FUplCsv.PostedFile.InputStream.Dispose();
FUplCsv.Dispose();
}
else
{
Response.Redirect("Default");
}
}
/// <summary>
/// Restituisce il nome del JOB caricato come descrizione digitata + nome file uploaded
/// </summary>
protected string jobDescription
{
get
{
string answ = $"{txtJobDescr.Text.Trim()} | {FUplCsv.FileName}";
return answ;
}
}
private void checkAndUploadFile()
{
// init dei dizionari errori/successi
Dictionary<string, string> newErrorList = new Dictionary<string, string>();
Dictionary<string, string> newSuccessList = new Dictionary<string, string>();
string jobName = "";
string sourceDir = "";
// STEP1: inizio controlli su nomi...
if (FUplCsv.FileName != "" && (FUplCsv.FileName.EndsWith(".txt") || FUplCsv.FileName.EndsWith(".csv")))
{
newSuccessList.Add("FILE INPUT", "OK Filename format");
}
else
{
newErrorList.Add("FILE INPUT", "WRONG Filename format (only *.csv and *.txt)");
}
// STEP 2: se NON HO errori faccio controllo files
if (newErrorList.Count == 0)
{
jobName = $"TMP{DateTime.Now.ToString("yyyyMMdd_HHmmss_fff")}";
// carico localmente files
sourceDir = uploadLocally(jobName);
// controllo i files...
checkFilesUploaded(sourceDir, ref newErrorList);
// elimino file locali...
fileMover.obj.setDirectory(sourceDir);
fileMover.obj.eliminaDir();
}
//step 3: se tutto ok procedo con upload...
if (newErrorList.Count == 0)
{
// creo record
DS_App.JobsListDataTable tabJobs = dataLayer.man.taJL.insertNew(jobDescription, devicesAuthProxy.stObj.utente);
if (tabJobs.Count == 1)
{
/*************************************************
* CON il nome JOB (ID) creato...
* - devo creare una folder x il job
* - nella folder devo salvare i 2 files
* - sposto folder in area IN
* - devo creare un file *.req (anche vuoto) della richiesta di calcolo (in area IN)
*************************************************/
// recupero riga...
DS_App.JobsListRow currJob = tabJobs[0];
// uso il nome job creato x le path temporanee con 16 char...
jobName = "J" + currJob.JobId.ToString("D9");
// carico localmente files
sourceDir = uploadLocally(jobName);
// sposto su cluster
string destDir = moveToCluster(jobName, sourceDir);
// aggiorno su DB
updateDbRecord(currJob, destDir);
}
else
{
newErrorList.Add("DB_JOB", "Error creating record on DB");
}
}
// se ho errori mostro......
if (newErrorList.Count + newSuccessList.Count > 0)
{
errorList = newErrorList;
successList = newSuccessList;
raiseEvent(ucEvType.ReqUpdateParent);
}
}
/// <summary>
/// Controllo dei fiels caricati localmente
/// </summary>
/// <param name="sourceDir"></param>
private void checkFilesUploaded(string sourceDir, ref Dictionary<string, string> newErrorList)
{
string[] linesDbIn;
string regExpHead = @"^\w*;\w*;\w*;\w*$"; ;
string regExpBodyA = memLayer.ML.CRS("regExpBodyA");// @"^\d+;(0|1);(pos|neg);\-?\d+(\,\d*)*$";
// controllo DB_IN
linesDbIn = File.ReadAllLines($"{sourceDir}DB_INPUT.csv");
checkFile(linesDbIn, regExpHead, regExpBodyA, "DB_INPUT.csv", ref newErrorList);
}
/// <summary>
/// controllo il file...
/// </summary>
/// <param name="linesDbIn"></param>
/// <param name="regExpHead"></param>
/// <param name="regExpBody"></param>
private void checkFile(string[] linesDbIn, string regExpHead, string regExpBody, string fileName, ref Dictionary<string, string> newErrorList)
{
// controllo abbia ALMENO 2 linee (testata + valore)
if (linesDbIn.Length > 1)
{
Regex rgxHead = new Regex(regExpHead);
Regex rgxBody = new Regex(regExpBody);
// controllo linea intestazione
if (!rgxHead.IsMatch(linesDbIn[0]))
{
newErrorList.Add($"{fileName}-Header", $"HEADER ERROR (mismatch): found --> {linesDbIn[0]}");
}
// controllo linee successive, SE supero i 10 errori ESCO comunque...
int maxErrors = memLayer.ML.CRI("maxErrors");
for (int i = 1; i < linesDbIn.Length; i++)
{
if (!rgxBody.IsMatch(linesDbIn[i]))
{
newErrorList.Add($"{fileName}-Line[{i}]", $"DATA ERROR (mismatch): --> {linesDbIn[i]}");
maxErrors--;
}
if (maxErrors <= 0)
{
break;
}
}
}
else
{
newErrorList.Add($"{fileName}-LineCount", "Expected almost 2 lines (header + data)");
}
}
/// <summary>
/// aggiornamento record su DB post upload
/// </summary>
/// <param name="currJob"></param>
/// <param name="destDir"></param>
private void updateDbRecord(DS_App.JobsListRow currJob, string destDir)
{
// registro trasferimento effettuato...
int sizeKb = (FUplCsv.PostedFile.ContentLength) / 1024;
// update record!
dataLayer.man.taJL.updateUpload(currJob.JobId, DateTime.Now, sizeKb, destDir);
}
/// <summary>
/// Sposta i dati da directory locale a cluster
/// </summary>
/// <param name="jobName"></param>
/// <param name="sourceDir"></param>
/// <returns></returns>
private static string moveToCluster(string jobName, string sourceDir)
{
// creo cartella in server target
string destDir = $"{memLayer.ML.CRS("clusterBaseDir")}\\IN\\"; // @"L:\IN\";
try
{
logger.lg.scriviLog($"Richiesta copia directory:{sourceDir} --> {destDir}\\{jobName}", tipoLog.INFO);
// sposto folder in dir target..
fileMover.DirectoryCopy(sourceDir, destDir + $"{jobName}\\", true);
}
catch (Exception exc)
{
logger.lg.scriviLog($"Eccezione in copia directory:{Environment.NewLine}{exc}", tipoLog.EXCEPTION);
}
try
{
if (memLayer.ML.CRB("reqWriteLocal"))
{
string srcDirOnly = sourceDir.Replace($"{jobName}\\", "");
logger.lg.scriviLog($"Richiesta scrittura file IN LOCALE: {srcDirOnly}\\{jobName}.req", tipoLog.INFO);
// aggiungo file di request locale...
File.WriteAllText($"{srcDirOnly}\\{jobName}.req", "");
// lo sposto!
fileMover.obj.copiaFile(srcDirOnly, destDir, $"{jobName}.req");
}
else
{
logger.lg.scriviLog($"Richiesta scrittura file IN remoto :{destDir}\\{jobName}.req", tipoLog.INFO);
// aggiungo file di request...
File.WriteAllText($"{destDir}\\{jobName}.req", "");
}
}
catch (Exception exc)
{
logger.lg.scriviLog($"Eccezione in creazione file req:{Environment.NewLine}{exc}", tipoLog.EXCEPTION);
}
return destDir;
}
/// <summary>
/// Carica localmente (sul server) i dati e restituisce path locale (compreso di jobName nella path)
/// </summary>
/// <param name="jobName"></param>
/// <returns></returns>
private string uploadLocally(string jobName)
{
// creo upload dir...
string sourceDir = Server.MapPath($"{memLayer.ML.CRS("tempUploadDir")}\\{jobName}\\");
fileMover.obj.setDirectory(sourceDir);
fileMover.obj.checkDir();
// proseguo con upload files...
FUplCsv.SaveAs($"{sourceDir}DB_INPUT.csv");
return sourceDir;
}
}
}