/// <summary> /// Get a zip file containing all shape files /// </summary> /// <remarks> /// HTTP GET call format:http://{server}/api/EPADelineate?watershedOutletLat=latValue&watershedOutletLon=lonValue /// </remarks> /// <param name="watershedOutletLat">Latidue of the watershed outlet location based on WGS84 datum</param> /// <param name="watershedOutletLon">Longitude of the watershed outlet location based on WGS84 datum</param> /// <returns>A zip file of all shape files, shape files data based on WGS84 datum</returns> public HttpResponseMessage GetShapeFiles(double watershedOutletLat, double watershedOutletLon) { HttpResponseMessage response = new HttpResponseMessage(); ServiceContext db = new ServiceContext(); ServiceLog serviceLog = null; try { var service = db.Services.First(s => s.APIName == "EPADelineateController.GetShapeFiles"); serviceLog = new ServiceLog { JobID = Guid.NewGuid().ToString(), ServiceID = service.ServiceID, CallTime = DateTime.Now, StartTime = DateTime.Now, RunStatus = RunStatus.Processing }; db.ServiceLogs.Add(serviceLog); db.SaveChanges(); serviceLog = db.ServiceLogs.First(s => s.JobID == serviceLog.JobID); Delineate(watershedOutletLat, watershedOutletLon); // Ref:http://stackoverflow.com/questions/12145390/how-to-set-downloading-file-name-in-asp-net-mvc-web-api // create a zip file of all shapes files string zipFilePath = Path.Combine(_targetShapeFileZipDirPath, "shapefiles.zip"); if (File.Exists(zipFilePath)) { File.Delete(zipFilePath); } ZipFile.CreateFromDirectory(_targetShapeFilesDirPath, zipFilePath); // load the zip file to memory MemoryStream ms = new MemoryStream(); using (FileStream file = new FileStream(zipFilePath, FileMode.Open, FileAccess.Read)) { file.CopyTo(ms); file.Close(); if (ms.Length == 0) { string errMsg = "No watershed exists for the selected outlet location."; logger.Error(errMsg); return Request.CreateErrorResponse(HttpStatusCode.NotFound, errMsg); } response.StatusCode = HttpStatusCode.OK; ms.Position = 0; response.Content = new StreamContent(ms); response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream"); // Ref: http://weblogs.asp.net/cibrax/archive/2011/04/25/implementing-caching-in-your-wcf-web-apis.aspx // set the browser to cache this response for 10 secs only response.Content.Headers.Expires = DateTime.Now.AddSeconds(10); response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment") { FileName = UEB.UEBSettings.WATERSHED_SHAPE_ZIP_FILE_NAME }; logger.Info("All shape files were zipped and sent to the client as a zip file."); } // clean up the temporary folders for shape files DirectoryInfo dir = new DirectoryInfo(_targetShapeFileGuidDirPath); dir.Delete(true); serviceLog.RunStatus = RunStatus.Success; serviceLog.FinishTime = DateTime.Now; db.SaveChanges(); } catch (Exception ex) { logger.Fatal(ex.Message); serviceLog.RunStatus = RunStatus.Error; serviceLog.FinishTime = DateTime.Now; serviceLog.Error = ex.Message; db.SaveChanges(); return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, ex.Message); } return response; }
public HttpResponseMessage PostRunUEB() { HttpResponseMessage response = new HttpResponseMessage(); ServiceContext db = new ServiceContext(); string modelRunRootPath = string.Empty; string uebInputPackageZipFileName = "ueb_input_package.zip"; string uebInputPackageZipFile = string.Empty; string uebExecutableFilesPath = string.Empty; string uebExecutionControlFileName = UEB.UEBSettings.UEB_EXECUTION_CONTROL_FILE_NAME; string msg = string.Empty; ServiceLog serviceLog = null; // get the ueb model package zip file from the request Stream uebPackageZipFileFromClient = null; try { var t_stream = this.Request.Content.ReadAsStreamAsync().ContinueWith(s => { uebPackageZipFileFromClient = s.Result; }); t_stream.Wait(); msg = string.Format("Input model package zip file was read from the http request."); logger.Info(msg); } catch (Exception ex) { logger.Fatal(ex.Message); return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, ex.Message); } if (uebPackageZipFileFromClient == null) { string errMsg = "No model package file was received from the client."; logger.Error(errMsg); response.StatusCode = HttpStatusCode.BadRequest; response.Content = new StringContent(errMsg); return response; } // generate a guid to pass on to the client as a job ID and use this as part of creating a unique folder // for model run output Guid jobGuid = Guid.NewGuid(); modelRunRootPath = Path.Combine(UEB.UEBSettings.WORKING_DIR_PATH, jobGuid.ToString(), UEB.UEBSettings.UEB_RUN_FOLDER_NAME); uebInputPackageZipFile = Path.Combine(modelRunRootPath, uebInputPackageZipFileName); Directory.CreateDirectory(modelRunRootPath); msg = string.Format("Directory ({0}) was created for running ueb model.", modelRunRootPath); logger.Info(msg); try { var service = db.Services.First(s => s.APIName == "RunUEBController.PostRunUEB"); serviceLog = new ServiceLog { JobID = jobGuid.ToString(), ServiceID = service.ServiceID, CallTime = DateTime.Now, StartTime = DateTime.Now, RunStatus = RunStatus.Processing }; db.ServiceLogs.Add(serviceLog); db.SaveChanges(); serviceLog = db.ServiceLogs.First(s => s.JobID == serviceLog.JobID); // save the recieved package file locally for ueb to use using (var fileStream = File.Create(uebInputPackageZipFile)) { uebPackageZipFileFromClient.CopyTo(fileStream); } msg = string.Format("Input model package zip file was saved: {0}.", uebInputPackageZipFile); logger.Info(msg); } catch (Exception ex) { serviceLog.RunStatus = RunStatus.Error; serviceLog.FinishTime = DateTime.Now; serviceLog.Error = ex.Message; db.SaveChanges(); logger.Fatal(ex.Message); return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, ex.Message); } // unzip the request zip file ZipFile.ExtractToDirectory(uebInputPackageZipFile, modelRunRootPath); // copy the UEB executables and dlls to model run folder uebExecutableFilesPath = UEB.UEBSettings.UEB_EXECUTABLE_DIR_PATH; string[] files = Directory.GetFiles(uebExecutableFilesPath); string fileName = string.Empty; string destFile = string.Empty; foreach (string file in files) { // Use static Path methods to extract only the file name from the path. fileName = Path.GetFileName(file); destFile = Path.Combine(modelRunRootPath, fileName); // Copy the file and overwrite destination file if they already exist. File.Copy(file, destFile, true); } //Run ueb in async mode RunUEB(modelRunRootPath, uebInputPackageZipFile, jobGuid.ToString()); UebRunStatusResponse uebRunStatus = new UebRunStatusResponse(); uebRunStatus.Message = "UEB execution has started."; uebRunStatus.RunJobID = jobGuid.ToString(); string jsonResponse = JsonConvert.SerializeObject(uebRunStatus, Formatting.Indented); response.StatusCode = HttpStatusCode.OK; response.Content = new StringContent(jsonResponse); return response; }
/// <summary> /// Creates UEB model package /// <remarks> /// POST is used since the input data needs to come in as a zip file in the body of the request /// and can't be sent as query parameter /// </remarks> /// </summary> /// <returns></returns> public HttpResponseMessage PostUEBPackageCreate() { string uebPackageBuildRequestJson = string.Empty; HttpResponseMessage response = new HttpResponseMessage(); Stream uebPackageBuildRequestZipFile = null; ServiceContext db = new ServiceContext(); ServiceLog serviceLog = null; var t_stream = this.Request.Content.ReadAsStreamAsync().ContinueWith(s => { uebPackageBuildRequestZipFile = s.Result; }); t_stream.Wait(); // generate a guid to pass on to the client as a job ID Guid jobGuid = Guid.NewGuid(); // set the package request processing root dir path _packageRequestProcessRootDirPath = Path.Combine(UEB.UEBSettings.WORKING_DIR_PATH, jobGuid.ToString()); // set other directory paths necessary for processing the request to build ueb package _sourceFilePath = _packageRequestProcessRootDirPath; _targetTempPackageFilePath = Path.Combine(_packageRequestProcessRootDirPath, UEB.UEBSettings.PACKAGE_FILES_OUTPUT_SUB_DIR_PATH); _targetPackageDirPath = Path.Combine(_packageRequestProcessRootDirPath, UEB.UEBSettings.PACKAGE_OUTPUT_SUB_DIR_PATH); // set the path for saving the client request zip file _clientPackageRequestDirPath = Path.Combine(_packageRequestProcessRootDirPath, UEB.UEBSettings.PACKAGE_BUILD_REQUEST_SUB_DIR_PATH); string packageRequestZipFile = Path.Combine(_clientPackageRequestDirPath, UEB.UEBSettings.PACKAGE_BUILD_REQUEST_ZIP_FILE_NAME); try { var service = db.Services.First(s => s.APIName == "GenerateUEBPackageController.PostUEBPackageCreate"); serviceLog = new ServiceLog { JobID = jobGuid.ToString(), ServiceID = service.ServiceID, CallTime = DateTime.Now, RunStatus = RunStatus.InQueue }; db.ServiceLogs.Add(serviceLog); db.SaveChanges(); serviceLog = db.ServiceLogs.First(s => s.JobID == serviceLog.JobID); if (Directory.Exists(_packageRequestProcessRootDirPath)) { Directory.Delete(_packageRequestProcessRootDirPath); } Directory.CreateDirectory(_packageRequestProcessRootDirPath); if (Directory.Exists(_targetTempPackageFilePath)) { Directory.Delete(_targetTempPackageFilePath); } Directory.CreateDirectory(_targetTempPackageFilePath); if (Directory.Exists(_clientPackageRequestDirPath)) { Directory.Delete(_clientPackageRequestDirPath); } Directory.CreateDirectory(_clientPackageRequestDirPath); using (var fileStream = File.Create(packageRequestZipFile)) { uebPackageBuildRequestZipFile.CopyTo(fileStream); } // unzip the request zip file ZipFile.ExtractToDirectory(packageRequestZipFile, _clientPackageRequestDirPath); } catch (Exception ex) { logger.Error(ex.Message); response.StatusCode = HttpStatusCode.BadRequest; response.Content = new StringContent(ex.Message); serviceLog.RunStatus = RunStatus.Error; serviceLog.Error = ex.Message; db.SaveChanges(); return response; } // read the file with json extension to a string - uebPackageBuildRequestJson string[] jsonFiles = Directory.GetFiles(_clientPackageRequestDirPath, "*.json"); if (jsonFiles.Length != 1) { string errMsg = "Either no json file was found in the package request or there are multiple json files"; logger.Error(errMsg); response.StatusCode = HttpStatusCode.BadRequest; response.Content = new StringContent(errMsg); serviceLog.RunStatus = RunStatus.Error; serviceLog.Error = errMsg; db.SaveChanges(); return response; } using (var fileReader = new StreamReader(jsonFiles[0])) { uebPackageBuildRequestJson = fileReader.ReadToEnd(); } UEB.UEBPackageRequest pkgRequest; try { pkgRequest = JsonConvert.DeserializeObject<UEB.UEBPackageRequest>(uebPackageBuildRequestJson); } catch (Exception ex) { logger.Error(ex.Message); response.StatusCode = HttpStatusCode.BadRequest; response.Content = new StringContent(ex.Message); serviceLog.RunStatus = RunStatus.Error; serviceLog.Error = ex.Message; db.SaveChanges(); return response; } // check if the client request is valid string validationResult = ValidateUEBPackageRequest(pkgRequest); if (string.IsNullOrEmpty(validationResult) == false) { logger.Error(validationResult); response.StatusCode = HttpStatusCode.BadRequest; response.Content = new StringContent(validationResult); serviceLog.RunStatus = RunStatus.Error; serviceLog.Error = validationResult; db.SaveChanges(); return response; } // if the domain file is a shape file, extract the domain zip file to the root processing dir path string domainFile = Path.Combine(_clientPackageRequestDirPath, pkgRequest.DomainFileName); if (Path.GetExtension(domainFile) == ".zip") { // unzip the domain shape zip file ZipFile.ExtractToDirectory(domainFile, _packageRequestProcessRootDirPath); } // copy all the files with extensions (.dat, .nc) that came with the client uebpackagerequest zip file // to the package root processing folder string[] files = Directory.GetFiles(_clientPackageRequestDirPath); string fileName = string.Empty; string destFile = string.Empty; foreach (string file in files) { if (Path.GetExtension(file) == ".nc" || Path.GetExtension(file) == ".dat") { // Use static Path methods to extract only the file name from the path. fileName = Path.GetFileName(file); destFile = Path.Combine(_packageRequestProcessRootDirPath, fileName); // Copy the file and overwrite destination file if they already exist. File.Copy(file, destFile, true); } } PackageCreationStatus pkgStatus = new PackageCreationStatus(); pkgStatus.Message = "UEB package build request is now in a job queue."; pkgStatus.PackageID = jobGuid.ToString(); string jsonResponse = JsonConvert.SerializeObject(pkgStatus, Formatting.Indented); response.StatusCode = HttpStatusCode.OK; response.Content = new StringContent(jsonResponse); //PK:2/11/2014 (Added): start the package build process - this would start the package build process for this request // if no other requests are in queue. Othewise it will start the build process for the build request that // has been in queue for the longest time (first-in and first-out principle) PackageBuilder uebPkgBuilder = new PackageBuilder(); int numberOfJobsStarted = uebPkgBuilder.Run(); logger.Info("Number of queued jobs started:" + numberOfJobsStarted); return response; }