using System; using System.Collections.Generic; using System.Text; using System.Configuration; using Amib.Threading; using System.Net; using System.IO; using System.Data; using System.Globalization; using System.Xml; using PipelineLib; using System.Diagnostics; namespace SmartFTPThread { public class SmartFTP { //Lista dei contrattiID private List reports; private SmartThreadPool smartThreadPool; private int maxActiveThreads; private int recordsPerThread; private int totalThreads; private string path; private string ambiente; private string cawTo_bin; private string cawToErrore; public SmartFTP(List reportsDaProcessare, string path, string ambiente, string cawTo_Bin, string argomentiCawToErrore) { reports = reportsDaProcessare; maxActiveThreads = Convert.ToInt32(ConfigurationManager.AppSettings["maxActiveThreads"]); recordsPerThread = Convert.ToInt32(ConfigurationManager.AppSettings["recordsPerThread"]); totalThreads = (int)Math.Ceiling(reports.Count / (double)recordsPerThread); this.path = path; this.ambiente = ambiente; this.cawTo_bin = cawTo_Bin; this.cawToErrore = argomentiCawToErrore; } public void Start(int idZip) { #region COPIA I PDF DAL DB foreach (ReportDaProcessare reportDaProcessare in reports) { byte[] stream = null; List parametri = new List(); Parametro p = new Parametro(); p.ParameterName = "id"; p.DbType = DbType.Int32; p.Value = reportDaProcessare.IdReport; parametri.Add(p); object report = DataAccess.ExecuteScalarStoredProcedure(DBProvider.SqlServer, "[dbo].[C6_S_readPDF]", parametri); if (report != null) stream = (byte[])report; else { throw new Exception("Errore nel file: " + reportDaProcessare.NomeFile + ", con IdReport: " + reportDaProcessare.IdReport + ", File non letto dal DB"); //continue; } //string path = ConfigurationManager.AppSettings["pathZIP"]; FileStream fs = null; BinaryWriter bw = null; //try //{ fs = File.Create(@path + "\\" + reportDaProcessare.NomeFile); bw = new BinaryWriter(fs); bw.Write(stream); p = new Parametro(); p.ParameterName = "tipoReport"; p.DbType = DbType.AnsiStringFixedLength; p.Value = reportDaProcessare.TipoReport; parametri.Add(p); p = new Parametro(); p.ParameterName = "idZip"; p.DbType = DbType.Int32; p.Value = idZip; parametri.Add(p); string query = ConfigurationManager.AppSettings["SP_GESTIONE_UPDATE_FTP"].ToString(); int ritorno = DataAccess.ExecuteNonQueryStoredProcedure(DBProvider.SqlServerStampeC6, query, parametri); if (fs != null) fs.Close(); if (bw != null) bw.Close(); } #endregion //Commentato perchè non copiava tutti i report su disco #region INIZIALIZZAZIONE SMART_THREADPOOL //try { // STPStartInfo stpStartInfo = new STPStartInfo(); // stpStartInfo.StartSuspended = true; // stpStartInfo.MaxWorkerThreads = maxActiveThreads; // stpStartInfo.MinWorkerThreads = 0; // stpStartInfo.IdleTimeout = 10; // smartThreadPool = new SmartThreadPool(stpStartInfo); // smartThreadPool.Start(); // WIGStartInfo wigStartInfo = new WIGStartInfo(); // wigStartInfo.StartSuspended = true; // Pipeline group = new Pipeline(smartThreadPool, int.MaxValue); // //assegna ad ogni thread un sottoinsieme di contratti // int j = 0; // for (int i = 0; i < totalThreads; i++) { // Worker worker; // //smartThreadPool.QueueWorkItem(new WorkItemCallback(this.DoWork), CIDs); // //counter += recordsPerThread; // //if (counter >= reports.Count) counter = reports.Count - 1; // if (j + recordsPerThread > reports.Count) { // worker = new Worker(reports.GetRange(j, reports.Count - j), path, idZip); // //smartThreadPool.QueueWorkItem(new WorkItemCallback(this.LocalCopy), reports.GetRange(j, reports.Count - j)); // } // else { // worker = new Worker(reports.GetRange(j, recordsPerThread), path, idZip); // //smartThreadPool.QueueWorkItem(new WorkItemCallback(this.LocalCopy), reports.GetRange(j, recordsPerThread)); // } // group.AddTask(worker); // j += recordsPerThread; // } #endregion #region ESECUZIONE SMART E RILASCIO RISORSE //group.execute(); // if (group.inException) { // //ScriviErroreNelDB(-292929, "Errore nello SmartFTP group.inException INIZIO", -292929, "SmartFTP", "SmartFTP"); // foreach (Task t in group.tasks) { // if (t.taskData.innerException != null) { // //Console.WriteLine(t.taskData.name + " eccezione=" + t.taskData.innerException.Message); // try // { // ScriviErroreNelDB(-292929, "Errore nello SmartFTP group.inException DENTRO: " + t.taskData.name + " __ " + getException(t.taskData.innerException), -292929, "SmartFTP", "SmartFTP"); // } // catch // { // } // } // } // //ScriviErroreNelDB(-292929, "Errore nello SmartFTP group.inException FINE", -292929, "SmartFTP", "SmartFTP"); // throw new Exception("Errore nello SmartFTP group.inException"); // //StartTng(ambiente, cawTo_bin, cawToErrore); // //return 1; // } // //return 0; //} //catch (Exception e) { // throw e; //} //finally { // smartThreadPool.Shutdown(); //} #endregion } private static void StartTng(string ambiente, string cawTo_Bin, string argomentiCaw) { if (!ambiente.Equals("SVILUPPO")) { Process processTng = new Process(); try { processTng = Process.Start(cawTo_Bin, argomentiCaw); while (!processTng.HasExited) ; } catch (Exception ex) { throw new Exception("cawTo_Bin: Non riesco ad eseguire " + cawTo_Bin + " sulla macchina " + System.Environment.MachineName + ":" + ex.Message); } finally { processTng.Close(); processTng.Dispose(); } } } private static void ScriviErroreNelDB(int codiceErrore, string descrizioErrore, int localeId, string nomePackage, string descrizionePackage) { int scriviErroreNelDB = int.Parse(ConfigurationManager.AppSettings["scriviErroreNelDB"]); if (scriviErroreNelDB == 1) { //try { List parametri = new List(); Parametro parametro = new Parametro(); parametro.DbType = DbType.Int32; parametro.ParameterName = "codiceErrore"; parametro.Value = codiceErrore; parametri.Add(parametro); parametro = new Parametro(); parametro.DbType = DbType.String; parametro.ParameterName = "descrizioErrore"; parametro.Value = descrizioErrore; parametri.Add(parametro); parametro = new Parametro(); parametro.DbType = DbType.DateTime; parametro.ParameterName = "dataTime"; parametro.Value = DateTime.Now; parametri.Add(parametro); parametro = new Parametro(); parametro.DbType = DbType.String; parametro.ParameterName = "localeID"; if (localeId == 0) parametro.Value = System.DBNull.Value; else parametro.Value = localeId; parametri.Add(parametro); parametro = new Parametro(); parametro.DbType = DbType.String; parametro.ParameterName = "descrizionePackage"; parametro.Value = descrizionePackage; parametri.Add(parametro); parametro = new Parametro(); parametro.DbType = DbType.String; parametro.ParameterName = "nomePackage"; parametro.Value = nomePackage; parametri.Add(parametro); DataAccess.ExecuteNonQueryStoredProcedure(DBProvider.SqlServerStampeC6, "[C6Mart].[UT_INSERT_ERROR]", parametri); //} //catch (Exception ex) { // DataBaseException dataBaseException = (DataBaseException)ex; // Console.WriteLine(dataBaseException.Message); //} } } private static string getException(Exception ecc) { const string aCapo = "#/n#"; string ritorno = ""; ritorno += aCapo; ritorno += " tipo: " + ecc.GetType().ToString() + aCapo; ritorno += " descrizione: " + ecc.Message + aCapo; ritorno += " sorgente: " + ecc.Source + aCapo; if (ecc.InnerException != null) { ritorno += " descrizione Inner: " + ecc.InnerException.Message + aCapo; ritorno += " sorgente Inner: " + ecc.InnerException.Source + aCapo; } ritorno += " traccia: " + FormattaErrore(ecc.StackTrace) + aCapo; return ritorno; } private static string FormattaErrore(string errore) { const string aCapo = "#/n#"; const string spazio = " "; string separatore1 = " at "; string separatore2 = " in "; string separatore3 = ":line "; string erroreInterno = errore.Replace(separatore1, "@"); string ritorno = aCapo; //nome metodo e tutto il resto string[] messaggioErrore = erroreInterno.Split('@'); string messaggioSenzaSpazi; string[] messaggioInterno; foreach (string messaggio in messaggioErrore) { messaggioSenzaSpazi = messaggio.Trim(); if (messaggioSenzaSpazi != "") { messaggioSenzaSpazi = messaggioSenzaSpazi.Replace(separatore2, "@"); messaggioInterno = messaggioSenzaSpazi.Split('@'); if (messaggioInterno.GetUpperBound(0) == 1) { ritorno += spazio + "metodo: " + messaggioInterno[0] + aCapo; string fileLineaSingolo = messaggioInterno[1].Replace(separatore3, "@"); string[] fileLinea = fileLineaSingolo.Split('@'); ritorno += spazio + "percorsoFile: " + fileLinea[0] + aCapo; ritorno += spazio + "linea: " + fileLinea[1] + aCapo; ritorno += aCapo; } else { ritorno += spazio + "metodo: " + messaggioInterno[0] + aCapo; } } } return ritorno; } public void StartAndWait() { smartThreadPool.Start(); smartThreadPool.WaitForIdle(); smartThreadPool.Shutdown(); } //public object DoWork(int[] TCID) { #region CODICE DI PROVA IN LOCALE SENZA FTP private object LocalCopy(object t) { List TCID = (List)t; for (int i = 0; i < TCID.Count; i++) { ReportDaProcessare reportDaProcessare = TCID[i]; byte[] stream = null; List parametri = new List(); Parametro p = new Parametro(); p.ParameterName = "id"; p.DbType = DbType.Int32; p.Value = reportDaProcessare.IdReport; parametri.Add(p); object report = DataAccess.ExecuteScalarStoredProcedure(DBProvider.SqlServer, "[dbo].[C6_S_readPDF]", parametri); if (report != null) stream = (byte[])report; else continue; //string path = ConfigurationManager.AppSettings["pathZIP"]; FileStream fs = null; BinaryWriter bw = null; try { fs = File.Create(@path + "\\" + reportDaProcessare.NomeFile); bw = new BinaryWriter(fs); bw.Write(stream); string query = ConfigurationManager.AppSettings["SP_GESTIONE_UPDATE_FTP"]; int ritorno = DataAccess.ExecuteNonQueryStoredProcedure(DBProvider.SqlServerStampeC6, query, parametri); } catch (Exception e) { //Console.WriteLine(e.ToString()); throw e; } if (fs != null) fs.Close(); if (bw != null) bw.Close(); } return null; } #endregion CODICE DI PROVA IN LOCALE SENZA FTP #region CODICE THREAD FTP private object DoWork(object t) { List TCID = (List)t; try { for (int i = 0; i < TCID.Count; i++) { ReportDaProcessare reportDaProcessare = TCID[i]; byte[] stream = null; List parametri = new List(); Parametro p = new Parametro(); p.ParameterName = "id"; p.DbType = DbType.Int32; p.Value = reportDaProcessare.IdReport; parametri.Add(p); object report = DataAccess.ExecuteScalarStoredProcedure(DBProvider.SqlServer, "[dbo].[C6_S_readPDF]", parametri); if (report != null) stream = (byte[])report; else continue; FtpWebRequest request = (FtpWebRequest)WebRequest.Create(ConfigurationManager.AppSettings["FTPServer"] + reportDaProcessare.NomeFile); //request.Proxy = new WebProxy("155.208.255.162:8088"); request.Method = WebRequestMethods.Ftp.UploadFile; request.ContentLength = stream.Length; request.Credentials = new NetworkCredential(ConfigurationManager.AppSettings["FTPUser"], ConfigurationManager.AppSettings["FTPPassword"]); byte[] buffer = new byte[4096]; using (Stream writer = request.GetRequestStream()) using (MemoryStream ms = new MemoryStream(stream)) { int bytesRead = 0; int totalBytes = 0; do { bytesRead = ms.Read(buffer, 0, buffer.Length); if (bytesRead > 0) { writer.Write(buffer, 0, bytesRead); totalBytes += bytesRead; } } while (bytesRead > 0); Console.WriteLine("Trasferiti {0} bytes per idReport {1} con nome file {2}", totalBytes, reportDaProcessare.IdReport, reportDaProcessare.NomeFile); //Setto come trasferito il file string query = ConfigurationManager.AppSettings["SP_GESTIONE_UPDATE_FTP"]; int ritorno = DataAccess.ExecuteNonQueryStoredProcedure(DBProvider.SqlServerStampeC6, query, parametri); } FtpWebResponse response = (FtpWebResponse)request.GetResponse(); //Console.WriteLine(response.StatusDescription + ", " + response.ResponseUri); response.Close(); //e.Result = true; } } catch (WebException ex) { Console.WriteLine(((FtpWebResponse)ex.Response).StatusDescription); Console.WriteLine(ex.Message); throw ex; //e.Result = false; } catch (DataBaseException ex) { Console.WriteLine(ex.Message); if (ex.InnerException != null) Console.WriteLine(ex.InnerException.Message); throw ex; //e.Result = false; } catch (Exception ex) { Console.WriteLine(ex.Message); if (ex.InnerException != null) Console.WriteLine(ex.InnerException.Message); throw ex; //e.Result = false; } return null; } #endregion CODICE THREAD FTP } public class Worker : Task { private List TCID; private string path; private int idZip; static int i = 0; public Worker(List TCID, string path, int idZip) { this.TCID = TCID; this.path = path; this.idZip = idZip; this.taskData = new PipelineContext(i.ToString(), this); i++; } public override object Elaborate(Dictionary input) { for (int i = 0; i < TCID.Count; i++) { ReportDaProcessare reportDaProcessare = TCID[i]; byte[] stream = null; List parametri = new List(); Parametro p = new Parametro(); p.ParameterName = "id"; p.DbType = DbType.Int32; p.Value = reportDaProcessare.IdReport; parametri.Add(p); object report = DataAccess.ExecuteScalarStoredProcedure(DBProvider.SqlServerStampeC6, "[dbo].[C6_S_readPDF]", parametri); if (report != null) stream = (byte[])report; else continue; //string path = ConfigurationManager.AppSettings["pathZIP"]; FileStream fs = null; BinaryWriter bw = null; //try { fs = File.Create(@path + "\\" + reportDaProcessare.NomeFile); bw = new BinaryWriter(fs); bw.Write(stream); p = new Parametro(); p.ParameterName = "tipoReport"; p.DbType = DbType.AnsiStringFixedLength; p.Value = reportDaProcessare.TipoReport; parametri.Add(p); p = new Parametro(); p.ParameterName = "idZip"; p.DbType = DbType.Int32; p.Value = idZip; parametri.Add(p); string query = ConfigurationManager.AppSettings["SP_GESTIONE_UPDATE_FTP"]; int ritorno = DataAccess.ExecuteNonQueryStoredProcedure(DBProvider.SqlServerStampeC6, query, parametri); //} //catch (Exception e) { // Console.WriteLine(e.ToString()); // throw new Exception(e.Message); //} if (fs != null) fs.Close(); if (bw != null) bw.Close(); } return null; } } }