/// <summary> /// Builds this instance for specified executor type. /// </summary> /// <typeparam name="TExecutor">The type of the executor.</typeparam> public static TExecutor Build <TExecutor>( ILoggerFactory logger, IConfigurationStore configStore, IServiceExceptionHandler serviceExceptionHandler, string customerUid = null, string userId = null, string userEmailAddress = null, IHeaderDictionary headers = null, IProductivity3dV1ProxyCoord productivity3dV1ProxyCoord = null, IProductivity3dV2ProxyCompaction productivity3dV2ProxyCompaction = null, ITransferProxyFactory persistantTransferProxyFactory = null, IFilterServiceProxy filterServiceProxy = null, ITRexImportFileProxy tRexImportFileProxy = null, IProjectRepository projectRepo = null, IHttpContextAccessor httpContextAccessor = null, IDataOceanClient dataOceanClient = null, ITPaaSApplicationAuthentication authn = null, ISchedulerProxy schedulerProxy = null, IPegasusClient pegasusClient = null, ICwsProjectClient cwsProjectClient = null, ICwsDeviceClient cwsDeviceClient = null, ICwsProfileSettingsClient cwsProfileSettingsClient = null, IWebRequest gracefulClient = null, INotificationHubClient notificationHubClient = null ) where TExecutor : RequestExecutorContainer, new() { ILogger log = null; if (logger != null) { log = logger.CreateLogger <RequestExecutorContainer>(); } var executor = new TExecutor(); executor.Initialise( log, configStore, serviceExceptionHandler, customerUid, userId, userEmailAddress, headers, productivity3dV1ProxyCoord, productivity3dV2ProxyCompaction, persistantTransferProxyFactory, filterServiceProxy, tRexImportFileProxy, projectRepo, httpContextAccessor, dataOceanClient, authn, schedulerProxy, pegasusClient, cwsProjectClient, cwsDeviceClient, cwsProfileSettingsClient, gracefulClient, notificationHubClient ); return(executor); }
public ScheduleResult ScheduleVetaJob( [FromServices] ISchedulerProxy scheduler, [FromQuery] Guid projectUid, [FromQuery] string fileName, [FromQuery] string machineNames, [FromQuery] Guid?filterUid, [FromQuery] CoordType coordType = CoordType.Northeast) { //TODO: Do we need to validate the parameters here as well as when the export url is called? //The URL to get the export data is here in this controller, construct it based on this request var exportDataUrl = $"{HttpContext.Request.Scheme}://{HttpContext.Request.Host}/api/v2/export/veta?projectUid={projectUid}&fileName={fileName}&coordType={coordType}"; if (filterUid.HasValue) { exportDataUrl = $"{exportDataUrl}&filterUid={filterUid}"; } if (!string.IsNullOrEmpty(machineNames)) { exportDataUrl = $"{exportDataUrl}&machineNames={machineNames}"; } return(ScheduleJob(exportDataUrl, fileName, scheduler)); }
public async Task <ImportedFileDescriptorSingleResult> CreateImportedFileDirectV6( [FromServices] ISchedulerProxy schedulerProxy, Guid projectUid, string filename, ImportedFileType importedFileType, DxfUnitsType dxfUnitsType, DateTime fileCreatedUtc, DateTime fileUpdatedUtc, DateTime?surveyedUtc = null) { if (importedFileType == ImportedFileType.ReferenceSurface) { ServiceExceptionHandler.ThrowServiceException(HttpStatusCode.BadRequest, 122); } FileImportDataValidator.ValidateUpsertImportedFileRequest(projectUid, importedFileType, dxfUnitsType, fileCreatedUtc, fileUpdatedUtc, UserEmailAddress, surveyedUtc, filename, null, null); Logger.LogInformation( $"{nameof(CreateImportedFileDirectV6)}: ProjectUID: `{projectUid}`, Filename: `{filename}` ImportedFileType: `{importedFileType}`, DxfUnitsType: `{dxfUnitsType}`, SurveyedUTC: `{(surveyedUtc == null ? "N/A" : surveyedUtc.ToString())}`"); //When debugging locally using Postman, remove this check so can do an update await ValidateFileDoesNotExist(projectUid.ToString(), filename, importedFileType, surveyedUtc, null, null); if (!MultipartRequestHelper.IsMultipartContentType(Request.ContentType)) { ServiceExceptionHandler.ThrowServiceException(HttpStatusCode.BadRequest, 58, $"Expected a multipart request, but got '{Request.ContentType}'"); } var tempFilePath = await HttpContext.Request.StreamFile(Guid.NewGuid().ToString(), Logger); var result = await UpsertFile(tempFilePath, filename, projectUid.ToString(), importedFileType, dxfUnitsType, fileCreatedUtc, fileUpdatedUtc, surveyedUtc, schedulerProxy); return(result); }
public async Task <ContractExecutionResult> CreateReferenceSurface( [FromQuery] Guid projectUid, [FromQuery] string filename, [FromQuery] DateTime fileCreatedUtc, [FromQuery] DateTime fileUpdatedUtc, [FromQuery] Guid parentUid, [FromQuery] double offset, [FromServices] ISchedulerProxy schedulerProxy, [FromServices] IPreferenceProxy prefProxy) { Logger.LogInformation($"{nameof(CreateReferenceSurface)}: projectUid {projectUid} filename: {filename} parentUid: {parentUid} offset: {offset}"); await ValidateProjectId(projectUid.ToString()); //Check parent design does exist var importedFiles = await ImportedFileRequestDatabaseHelper.GetImportedFileList(projectUid.ToString(), Logger, UserId, ProjectRepo); var parent = importedFiles.FirstOrDefault(i => i.ImportedFileUid == parentUid.ToString()); if (parent == null) { ServiceExceptionHandler.ThrowServiceException(HttpStatusCode.BadRequest, 120); } //Fill in file name if not provided if (string.IsNullOrEmpty(filename)) { filename = await DefaultReferenceSurfaceName(prefProxy, offset, Path.GetFileNameWithoutExtension(parent.Name)); } //Validate parameters FileImportDataValidator.ValidateUpsertImportedFileRequest(projectUid, ImportedFileType.ReferenceSurface, DxfUnitsType.Meters, fileCreatedUtc, fileUpdatedUtc, UserEmailAddress, null, filename, parentUid, offset); //Check reference surface does not exist await ValidateFileDoesNotExist(projectUid.ToString(), filename, ImportedFileType.ReferenceSurface, null, parentUid, offset); var importedFileResult = await UpsertFileInternal(filename, null, projectUid, ImportedFileType.ReferenceSurface, DxfUnitsType.Meters, fileCreatedUtc, fileUpdatedUtc, null, schedulerProxy, parentUid, offset); //If parent design is deactivated then deactivate reference surface if (!parent.IsActivated) { var filesToUpdate = new Dictionary <Guid, bool>(); filesToUpdate.Add(new Guid(importedFileResult.ImportedFileDescriptor.ImportedFileUid), false); await DoActivationAndNotification(projectUid.ToString(), filesToUpdate); importedFiles = await ImportedFileRequestDatabaseHelper.GetImportedFileList(projectUid.ToString(), Logger, UserId, ProjectRepo); importedFileResult.ImportedFileDescriptor = importedFiles.SingleOrDefault(i => i.ImportedFileUid == importedFileResult.ImportedFileDescriptor.ImportedFileUid); } Logger.LogInformation( $"{nameof(CreateReferenceSurface)}: Completed successfully. Response: {JsonConvert.SerializeObject(importedFileResult)}"); return(importedFileResult); }
public async Task <ScheduleJobResult> BackgroundUpload( FlowFile file, [FromQuery] Guid projectUid, [FromQuery] ImportedFileType importedFileType, [FromQuery] DxfUnitsType dxfUnitsType, [FromQuery] DateTime fileCreatedUtc, [FromQuery] DateTime fileUpdatedUtc, [FromQuery] DateTime?surveyedUtc, [FromServices] ISchedulerProxy scheduler, [FromServices] ITransferProxyFactory transferProxyFactory) { if (importedFileType == ImportedFileType.ReferenceSurface) { ServiceExceptionHandler.ThrowServiceException(HttpStatusCode.BadRequest, 122); } FlowJsFileImportDataValidator.ValidateUpsertImportedFileRequest( file, projectUid, importedFileType, dxfUnitsType, fileCreatedUtc, fileUpdatedUtc, UserEmailAddress, surveyedUtc, null, null); Logger.LogInformation( $"{nameof(BackgroundUpload)}: file: {file.flowFilename} path {file.path} projectUid {projectUid} ImportedFileType: {importedFileType} " + $"DxfUnitsType: {dxfUnitsType} surveyedUtc {(surveyedUtc == null ? "N/A" : surveyedUtc.ToString())}"); if (string.Equals(Request.Method, HttpMethod.Post.ToString(), StringComparison.OrdinalIgnoreCase)) { await ValidateFileDoesNotExist(projectUid.ToString(), file.flowFilename, importedFileType, surveyedUtc, null, null); } var s3Path = $"project/importedfile/{Guid.NewGuid()}.dat"; var fileStream = System.IO.File.Open(file.path, FileMode.Open, FileAccess.Read); var transferProxy = transferProxyFactory.NewProxy(TransferProxyType.Temporary); transferProxy.Upload(fileStream, s3Path); var baseUrl = Request.Host.ToUriComponent(); // The QueryString will have values in it, so it's safe to add extra queries with the & as opposed to ?, then & var callbackUrl = $"http://{baseUrl}/internal/v6/importedfile{Request.QueryString}"; callbackUrl += $"&filename={WebUtility.UrlEncode(file.flowFilename)}&awsFilePath={WebUtility.UrlEncode(s3Path)}"; Logger.LogInformation($"{nameof(BackgroundUpload)}: baseUrl {callbackUrl}"); var executionTimeout = ConfigStore.GetValueInt("PEGASUS_EXECUTION_TIMEOUT_MINS", 5) * 60000;//minutes converted to millisecs var request = new ScheduleJobRequest { Filename = file.flowFilename, Method = "GET", // match the internal upload Method Url = callbackUrl, Timeout = executionTimeout }; request.SetStringPayload(string.Empty); var headers = Request.Headers.GetCustomHeaders(); return(await scheduler.ScheduleBackgroundJob(request, headers)); }
public async Task <ReturnLongV5Result> UpsertImportedFileV5TBC( [FromRoute] long projectId, [FromBody] ImportedFileTbc importedFileTbc, [FromServices] ISchedulerProxy schedulerProxy) { // MobileLinework .kml/.kmz files are sent along with linework files // we need to suppress any error and return as if all ok. // however we won't have a LegacyFileId to return - hmmm hope Business centre ignores this if (importedFileTbc.ImportedFileTypeId == ImportedFileType.MobileLinework) { Logger.LogInformation( $"{nameof(UpsertImportedFileV5TBC)}: Ignore MobileLinework from BusinessCentre. projectId {projectId} importedFile: {JsonConvert.SerializeObject(importedFileTbc)}"); return(ReturnLongV5Result.CreateLongV5Result(HttpStatusCode.OK, -1)); } // this also validates that this customer has access to the projectUid var project = await ProjectRequestHelper.GetProjectForCustomer(new Guid(CustomerUid), new Guid(UserId), projectId, Logger, ServiceExceptionHandler, CwsProjectClient, customHeaders); var projectUid = project.ProjectId; importedFileTbc = FileImportV5TBCDataValidator.ValidateUpsertImportedFileRequest(new Guid(projectUid), importedFileTbc); Logger.LogInformation( $"{nameof(UpsertImportedFileV5TBC)}: projectId {projectId} projectUid {projectUid} importedFile: {JsonConvert.SerializeObject(importedFileTbc)}"); var fileEntry = await TccHelper.GetFileInfoFromTccRepository(importedFileTbc, Logger, ServiceExceptionHandler, FileRepo); await TccHelper.CopyFileWithinTccRepository(importedFileTbc, CustomerUid, projectUid, FileSpaceId, Logger, ServiceExceptionHandler, FileRepo).ConfigureAwait(false); ImportedFileDescriptorSingleResult importedFileResult; using (var ms = await TccHelper.GetFileStreamFromTcc(importedFileTbc, Logger, ServiceExceptionHandler, FileRepo)) { importedFileResult = await UpsertFileInternal(importedFileTbc.Name, ms, new Guid(projectUid), importedFileTbc.ImportedFileTypeId, importedFileTbc.ImportedFileTypeId == ImportedFileType.Linework ?importedFileTbc.LineworkFile.DxfUnitsTypeId : DxfUnitsType.Meters, fileEntry.createTime, fileEntry.modifyTime, importedFileTbc.ImportedFileTypeId == ImportedFileType.SurveyedSurface ?importedFileTbc.SurfaceFile.SurveyedUtc : (DateTime?)null, schedulerProxy); } // Automapper maps src.ImportedFileId to LegacyFileId, so this IS the one sent to TRex and used to ref via TCC var response = importedFileResult != null ? ReturnLongV5Result.CreateLongV5Result(HttpStatusCode.OK, importedFileResult.ImportedFileDescriptor.LegacyFileId) : ReturnLongV5Result.CreateLongV5Result(HttpStatusCode.InternalServerError, -1); Logger.LogInformation( $"{nameof(UpsertImportedFileV5TBC)}: Completed successfully. Response: {response} importedFile: {JsonConvert.SerializeObject(importedFileResult)}"); return(response); }
public async Task <ImportedFileDescriptorSingleResult> InternalImportedFileV6( [FromQuery] string filename, [FromQuery] string awsFilePath, [FromQuery] Guid projectUid, [FromQuery] ImportedFileType importedFileType, [FromQuery] DxfUnitsType dxfUnitsType, [FromQuery] DateTime fileCreatedUtc, [FromQuery] DateTime fileUpdatedUtc, [FromQuery] DateTime?surveyedUtc, [FromServices] ITransferProxyFactory transferProxyFactory, [FromServices] ISchedulerProxy schedulerProxy) { if (importedFileType == ImportedFileType.ReferenceSurface) { ServiceExceptionHandler.ThrowServiceException(HttpStatusCode.BadRequest, 122); } ImportedFileDescriptorSingleResult importedFileResult = null; var transferProxy = transferProxyFactory.NewProxy(TransferProxyType.Temporary); Logger.LogInformation( $"{nameof(InternalImportedFileV6)}:. filename: {filename} awspath {awsFilePath} projectUid {projectUid} ImportedFileType: {importedFileType} " + $"DxfUnitsType: {dxfUnitsType} surveyedUtc {(surveyedUtc == null ? "N/A" : surveyedUtc.ToString())}"); // Retrieve the stored file from AWS var fileResult = await transferProxy.Download(awsFilePath); if (fileResult == null) { ServiceExceptionHandler.ThrowServiceException(HttpStatusCode.InternalServerError, 55); } using (var ms = new MemoryStream()) { // Depending on the size of the file in S3, the stream returned may or may not support seeking // Which we need to TCC to know the length of the file (can't find the length, if you can't seek). // To solve this, we have to download the entire stream here and copy to memory. // Allowing TCC to upload the file. // Not the best solution for extra large files, but TCC doesn't support uploading without file size AFAIK fileResult.FileStream.CopyTo(ms); importedFileResult = await UpsertFileInternal(filename, ms, projectUid, importedFileType, dxfUnitsType, fileCreatedUtc, fileUpdatedUtc, surveyedUtc, schedulerProxy); } Logger.LogInformation( $"{nameof(InternalImportedFileV6)}: Completed successfully. Response: {JsonConvert.SerializeObject(importedFileResult)}"); return(importedFileResult); }
public ScheduleResult ScheduleSurfaceJob( [FromQuery] Guid projectUid, [FromQuery] string fileName, [FromQuery] double?tolerance, [FromQuery] Guid?filterUid, [FromServices] ISchedulerProxy scheduler) { //TODO: Do we need to validate the parameters here as well as when the export url is called? var exportDataUrl = $"{HttpContext.Request.Scheme}://{HttpContext.Request.Host}/api/v2/export/surface?projectUid={projectUid}&fileName={fileName}&filterUid={filterUid}&tolerance={tolerance}"; return(ScheduleJob(exportDataUrl, fileName, scheduler)); }
/// <summary> /// Schedule an export job wit the scheduler /// </summary> private ScheduleResult ScheduleJob(string exportDataUrl, string fileName, ISchedulerProxy scheduler, int?timeout = null) { if (timeout == null) { var configStoreTimeout = ConfigStore.GetValueInt("SCHEDULED_JOB_TIMEOUT"); timeout = configStoreTimeout > 0 ? configStoreTimeout : FIVE_MIN_SCHEDULER_TIMEOUT; } var request = new ScheduleJobRequest { Url = exportDataUrl, Filename = fileName, Timeout = timeout }; return(WithServiceExceptionTryExecute(() => new ScheduleResult { JobId = scheduler.ScheduleExportJob(request, Request.Headers.GetCustomHeaders()).Result?.JobId })); }
public ScheduleResult ScheduleMachinePassesJob( [FromQuery] Guid projectUid, [FromQuery] int coordType, [FromQuery] int outputType, [FromQuery] bool restrictOutput, [FromQuery] bool rawDataOutput, [FromQuery] string fileName, [FromQuery] Guid?filterUid, [FromServices] ISchedulerProxy scheduler) { //TODO: Do we need to validate the parameters here as well as when the export url is called? //The URL to get the export data is here in this controller, construct it based on this request var exportDataUrl = $"{HttpContext.Request.Scheme}://{HttpContext.Request.Host}/api/v2/export/machinepasses?projectUid={projectUid}&fileName={fileName}&filterUid={filterUid}" + $"&coordType={coordType}&outputType={outputType}&restrictOutput={restrictOutput}&rawDataOutput={rawDataOutput}"; return(ScheduleJob(exportDataUrl, fileName, scheduler)); }
/// <summary> /// Common file processing method used by all importedFile endpoints. /// </summary> private async Task <ImportedFileDescriptorSingleResult> UpsertFile( string tmpFilePath, string filename, string projectUid, ImportedFileType importedFileType, DxfUnitsType dxfUnitsType, DateTime fileCreatedUtc, DateTime fileUpdatedUtc, DateTime?surveyedUtc, ISchedulerProxy schedulerProxy) { if (!System.IO.File.Exists(tmpFilePath)) { ServiceExceptionHandler.ThrowServiceException(HttpStatusCode.BadRequest, 55); } using (var fileStream = new FileStream(tmpFilePath, FileMode.Open)) { return(await UpsertFileInternal(filename, fileStream, Guid.Parse(projectUid), importedFileType, dxfUnitsType, fileCreatedUtc, fileUpdatedUtc, surveyedUtc, schedulerProxy)); } }
public void Initialise(ILogger logger, IConfigurationStore configStore, IServiceExceptionHandler serviceExceptionHandler, string customerUid, string userId = null, string userEmailAddress = null, IHeaderDictionary headers = null, IProductivity3dV1ProxyCoord productivity3dV1ProxyCoord = null, IProductivity3dV2ProxyCompaction productivity3dV2ProxyCompaction = null, ITransferProxyFactory persistantTransferProxyFactory = null, IFilterServiceProxy filterServiceProxy = null, ITRexImportFileProxy tRexImportFileProxy = null, IProjectRepository projectRepo = null, IHttpContextAccessor httpContextAccessor = null, IDataOceanClient dataOceanClient = null, ITPaaSApplicationAuthentication authn = null, ISchedulerProxy schedulerProxy = null, IPegasusClient pegasusClient = null, ICwsProjectClient cwsProjectClient = null, ICwsDeviceClient cwsDeviceClient = null, ICwsProfileSettingsClient cwsProfileSettingsClient = null, IWebRequest gracefulClient = null, INotificationHubClient notificationHubClient = null) { log = logger; this.configStore = configStore; this.serviceExceptionHandler = serviceExceptionHandler; this.customerUid = customerUid; this.userId = userId; this.userEmailAddress = userEmailAddress; this.customHeaders = headers; this.productivity3dV1ProxyCoord = productivity3dV1ProxyCoord; this.productivity3dV2ProxyCompaction = productivity3dV2ProxyCompaction; this.persistantTransferProxyFactory = persistantTransferProxyFactory; this.filterServiceProxy = filterServiceProxy; this.tRexImportFileProxy = tRexImportFileProxy; this.projectRepo = projectRepo; this.httpContextAccessor = httpContextAccessor; this.dataOceanClient = dataOceanClient; this.authn = authn; this.schedulerProxy = schedulerProxy; this.pegasusClient = pegasusClient; this.cwsProjectClient = cwsProjectClient; this.cwsDeviceClient = cwsDeviceClient; this.cwsProfileSettingsClient = cwsProfileSettingsClient; this.gracefulClient = gracefulClient; this.notificationHubClient = notificationHubClient; }
public async Task <ImportedFileDescriptorSingleResult> SyncUpload( [FromServices] ISchedulerProxy schedulerProxy, FlowFile file, [FromQuery] Guid projectUid, [FromQuery] ImportedFileType importedFileType, [FromQuery] DxfUnitsType dxfUnitsType, [FromQuery] DateTime fileCreatedUtc, [FromQuery] DateTime fileUpdatedUtc, [FromQuery] DateTime?surveyedUtc) { if (importedFileType == ImportedFileType.ReferenceSurface) { ServiceExceptionHandler.ThrowServiceException(HttpStatusCode.BadRequest, 122); } // Validate the file FlowJsFileImportDataValidator.ValidateUpsertImportedFileRequest( file, projectUid, importedFileType, dxfUnitsType, fileCreatedUtc, fileUpdatedUtc, UserEmailAddress, surveyedUtc, null, null); Logger.LogInformation( $"{nameof(SyncUpload)}: file: {file.flowFilename} path {file.path} projectUid {projectUid} ImportedFileType: {importedFileType} " + $"DxfUnitsType: {dxfUnitsType} surveyedUtc {(surveyedUtc == null ? "N/A" : surveyedUtc.ToString())}"); await ValidateFileDoesNotExist(projectUid.ToString(), file.flowFilename, importedFileType, surveyedUtc, null, null); ContractExecutionResult importedFileResult; using (var fileStream = System.IO.File.Open(file.path, FileMode.Open, FileAccess.Read)) { importedFileResult = await UpsertFileInternal(file.flowFilename, fileStream, projectUid, importedFileType, dxfUnitsType, fileCreatedUtc, fileUpdatedUtc, surveyedUtc, schedulerProxy); } Logger.LogInformation( $"{nameof(SyncUpload)}: Completed successfully. Response: {JsonConvert.SerializeObject(importedFileResult)}"); return(importedFileResult as ImportedFileDescriptorSingleResult); }
public Task <ImportedFileDescriptorSingleResult> UpsertImportedFileV6( [FromServices] ISchedulerProxy schedulerProxy, FlowFile file, [FromQuery] Guid projectUid, [FromQuery] ImportedFileType importedFileType, [FromQuery] DxfUnitsType dxfUnitsType, [FromQuery] DateTime fileCreatedUtc, [FromQuery] DateTime fileUpdatedUtc, [FromQuery] DateTime?surveyedUtc = null) { if (importedFileType == ImportedFileType.ReferenceSurface) { ServiceExceptionHandler.ThrowServiceException(HttpStatusCode.BadRequest, 122); } FlowJsFileImportDataValidator.ValidateUpsertImportedFileRequest(file, projectUid, importedFileType, dxfUnitsType, fileCreatedUtc, fileUpdatedUtc, UserEmailAddress, surveyedUtc, null, null); Logger.LogInformation( $"{nameof(UpsertImportedFileV6)}: file: {JsonConvert.SerializeObject(file)} projectUid {projectUid} ImportedFileType: {importedFileType} DxfUnitsType: {dxfUnitsType} surveyedUtc {(surveyedUtc == null ? "N/A" : surveyedUtc.ToString())}"); return(UpsertFile(file.path, file.flowFilename, projectUid.ToString(), importedFileType, dxfUnitsType, fileCreatedUtc, fileUpdatedUtc, surveyedUtc, schedulerProxy)); }
public ScheduleResult ScheduleSnakepitJob( [FromServices] ISchedulerProxy scheduler, [FromQuery] Guid projectUid, [FromQuery] string fileName ) { //The URL to get the export data is in snakepit construct url from configuration var snakepitHost = ConfigStore.GetValueString("SNAKEPIT_HOST", null); if (!string.IsNullOrEmpty(snakepitHost)) { var exportDataUrl = $"{HttpContext.Request.Scheme}://{snakepitHost}/export{HttpContext.Request.QueryString.ToString()}"; return(ScheduleJob(exportDataUrl, fileName, scheduler, 3 * FIVE_MIN_SCHEDULER_TIMEOUT)); } throw new ServiceException(HttpStatusCode.InternalServerError, new ContractExecutionResult( ContractExecutionStatesEnum.InternalProcessingError, "Missing SNAKEPIT_HOST environment variable" ) ); }
/// <summary> /// Common file processing method used by all importedFile endpoints. /// </summary> protected async Task <ImportedFileDescriptorSingleResult> UpsertFileInternal( string filename, Stream fileStream, Guid projectUid, ImportedFileType importedFileType, DxfUnitsType dxfUnitsType, DateTime fileCreatedUtc, DateTime fileUpdatedUtc, DateTime?surveyedUtc, ISchedulerProxy schedulerProxy, Guid?parentUid = null, double?offset = null) { ImportedFileDescriptorSingleResult importedFile = null; var existing = await ImportedFileRequestDatabaseHelper .GetImportedFileForProject (projectUid.ToString(), filename, importedFileType, surveyedUtc, Logger, ProjectRepo, offset, parentUid) .ConfigureAwait(false); var creating = existing == null; Logger.LogInformation( creating ? $"{nameof(UpsertFileInternal)}. file doesn't exist already in DB: {filename} projectUid {projectUid} ImportedFileType: {importedFileType} surveyedUtc {(surveyedUtc == null ? "N/A" : surveyedUtc.ToString())} parentUid {parentUid} offset: {offset}" : $"{nameof(UpsertFileInternal)}. file exists already in DB. Will be updated: {JsonConvert.SerializeObject(existing)}"); FileDescriptor fileDescriptor = null; var importedFileUid = creating ? Guid.NewGuid() : Guid.Parse(existing.ImportedFileUid); var dataOceanFileName = DataOceanFileUtil.DataOceanFileName(filename, importedFileType == ImportedFileType.SurveyedSurface || importedFileType == ImportedFileType.GeoTiff, importedFileUid, surveyedUtc); if (importedFileType == ImportedFileType.ReferenceSurface) { //FileDescriptor not used for reference surface but validation requires values fileDescriptor = FileDescriptor.CreateFileDescriptor("Not applicable", "Not applicable", filename); } else { if (IsTRexDesignFileType(importedFileType)) { fileDescriptor = ProjectRequestHelper.WriteFileToS3Repository( fileStream, projectUid.ToString(), filename, importedFileType == ImportedFileType.SurveyedSurface, surveyedUtc, Logger, ServiceExceptionHandler, persistantTransferProxyFactory.NewProxy(TransferProxyType.DesignImport)); } //This is needed for ATs. fileDescriptor = FileDescriptor.CreateFileDescriptor( FileSpaceId, $"/{CustomerUid}/{projectUid}", filename); if (importedFileType == ImportedFileType.Linework || importedFileType == ImportedFileType.GeoTiff) { //save copy to DataOcean await DataOceanHelper.WriteFileToDataOcean( fileStream, DataOceanRootFolderId, CustomerUid, projectUid.ToString(), dataOceanFileName, Logger, ServiceExceptionHandler, DataOceanClient, Authorization, importedFileUid, ConfigStore); } } if (creating) { var createImportedFile = new CreateImportedFile( projectUid, filename, fileDescriptor, importedFileType, surveyedUtc, dxfUnitsType, fileCreatedUtc, fileUpdatedUtc, DataOceanRootFolderId, parentUid, offset, importedFileUid, dataOceanFileName); importedFile = await WithServiceExceptionTryExecuteAsync(() => RequestExecutorContainerFactory .Build <CreateImportedFileExecutor>( LoggerFactory, ConfigStore, ServiceExceptionHandler, CustomerUid, UserId, UserEmailAddress, customHeaders, productivity3dV2ProxyCompaction : Productivity3dV2ProxyCompaction, persistantTransferProxyFactory : persistantTransferProxyFactory, tRexImportFileProxy : tRexImportFileProxy, projectRepo : ProjectRepo, dataOceanClient : DataOceanClient, authn : Authorization, schedulerProxy : schedulerProxy, cwsProjectClient : CwsProjectClient) .ProcessAsync(createImportedFile) ) as ImportedFileDescriptorSingleResult; Logger.LogInformation( $"{nameof(UpsertFileInternal)}: Create completed successfully. Response: {JsonConvert.SerializeObject(importedFile)}"); } else { // this also validates that this customer has access to the projectUid var project = await ProjectRequestHelper.GetProject(projectUid, new Guid(CustomerUid), new Guid(UserId), Logger, ServiceExceptionHandler, CwsProjectClient, customHeaders); var importedFileUpsertEvent = new UpdateImportedFile( projectUid, project.ShortRaptorProjectId, importedFileType, (importedFileType == ImportedFileType.SurveyedSurface || importedFileType == ImportedFileType.GeoTiff) ? surveyedUtc : null, dxfUnitsType, fileCreatedUtc, fileUpdatedUtc, fileDescriptor, Guid.Parse(existing?.ImportedFileUid), existing.ImportedFileId, DataOceanRootFolderId, offset, dataOceanFileName); importedFile = await WithServiceExceptionTryExecuteAsync(() => RequestExecutorContainerFactory .Build <UpdateImportedFileExecutor>( LoggerFactory, ConfigStore, ServiceExceptionHandler, CustomerUid, UserId, UserEmailAddress, customHeaders, productivity3dV2ProxyCompaction : Productivity3dV2ProxyCompaction, tRexImportFileProxy : tRexImportFileProxy, projectRepo : ProjectRepo, dataOceanClient : DataOceanClient, authn : Authorization, schedulerProxy : schedulerProxy, cwsProjectClient : CwsProjectClient) .ProcessAsync(importedFileUpsertEvent) ) as ImportedFileDescriptorSingleResult; Logger.LogInformation( $"{nameof(UpsertFileInternal)}: Update completed successfully. Response: {JsonConvert.SerializeObject(importedFile)}"); } await NotificationHubClient.Notify(new ProjectChangedNotification(projectUid)); return(importedFile); }