Ejemplo n.º 1
0
        private async Task SubmitAggregation(string externalId, CancellationToken cancellationToken)
        {
            var submitContext = new SubmitContext
            {
                TenantId                     = _connectorConfigModel.TenantIdAsGuid,
                ConnectorConfigId            = _connectorConfigModel.IdAsGuid,
                ApiClientFactorySettings     = ConnectorApiAuthHelper.GetApiClientFactorySettings(),
                AuthenticationHelperSettings = ConnectorApiAuthHelper.GetAuthenticationHelperSettings(_connectorConfigModel.TenantDomainName),
                CoreMetaData                 = new List <SubmissionMetaDataModel>(),
                SourceMetaData               = new List <SubmissionMetaDataModel>(),
                Filters           = _connectorConfigModel.Filters,
                CancellationToken = cancellationToken
            };

            submitContext.CoreMetaData.Add(new SubmissionMetaDataModel(Fields.ExternalId, type: nameof(String), value: externalId.ToString()));

            // Aggregations need to have the special "ItemTypeId" field set to "1" to identify them as being an aggregation.
            // Submissions that omit this field are identified as items.
            submitContext.CoreMetaData.Add(new SubmissionMetaDataModel(Fields.ItemTypeId, type: nameof(Double), value: "1"));

            // Note we do not set the ParentExternalId of the aggregation - in most cases aggregations don't have a parent.

            submitContext.CoreMetaData.Add(new SubmissionMetaDataModel(Fields.SourceLastModifiedDate, type: nameof(DateTime), value: DateTime.UtcNow.ToString("O")));

            submitContext.CoreMetaData.Add(new SubmissionMetaDataModel(Fields.Title, type: nameof(String), value: $"Fake Record Folder from {_connectorConfigModel.Id}"));
            submitContext.CoreMetaData.Add(new SubmissionMetaDataModel(Fields.Author, type: nameof(String), value: "Record ReferenceConnectorSF"));
            submitContext.CoreMetaData.Add(new SubmissionMetaDataModel(Fields.SourceCreatedDate, type: nameof(DateTime), value: DateTime.UtcNow.ToString("O")));
            submitContext.CoreMetaData.Add(new SubmissionMetaDataModel(Fields.SourceCreatedBy, type: nameof(String), value: "ReferenceConnectorSF"));
            submitContext.CoreMetaData.Add(new SubmissionMetaDataModel(Fields.SourceLastModifiedBy, type: nameof(String), value: "ReferenceConnectorSF"));
            submitContext.CoreMetaData.Add(new SubmissionMetaDataModel(Fields.Location, type: nameof(String), value: "Fake Record Folder"));
            submitContext.CoreMetaData.Add(new SubmissionMetaDataModel(Fields.MediaType, type: nameof(String), value: "Electronic"));
            submitContext.CoreMetaData.Add(new SubmissionMetaDataModel(Fields.ContentVersion, type: nameof(String), value: "1.0"));

            submitContext.SourceMetaData.Add(new SubmissionMetaDataModel("Checkin Comments", type: nameof(String), value: "Some checkin comments"));

            // Submit the aggregation!
            try
            {
                await _aggregationSubmitPipeline.Submit(submitContext).ConfigureAwait(false);

                HandleSubmitPipelineResult(submitContext);
            }
            catch (Exception)
            {
                // Something went wrong trying to submit the item.
                // Dead-letter the item to a durable data store where it can be retried later. (e.g., a message broker).
            }
        }
Ejemplo n.º 2
0
        private async Task SubmitAuditEvent(string itemExternalId, CancellationToken cancellationToken)
        {
            var submitContext = new SubmitContext
            {
                TenantId                     = _connectorConfigModel.TenantIdAsGuid,
                ConnectorConfigId            = _connectorConfigModel.IdAsGuid,
                ApiClientFactorySettings     = ConnectorApiAuthHelper.GetApiClientFactorySettings(),
                AuthenticationHelperSettings = ConnectorApiAuthHelper.GetAuthenticationHelperSettings(_connectorConfigModel.TenantDomainName),
                CoreMetaData                 = new List <SubmissionMetaDataModel>(),
                SourceMetaData               = new List <SubmissionMetaDataModel>(),
                Filters           = _connectorConfigModel.Filters,
                CancellationToken = cancellationToken
            };

            // Associate the audit event with the item with the item external id.
            submitContext.CoreMetaData.Add(new SubmissionMetaDataModel(Fields.AuditEvent.ExternalId, type: nameof(String), value: itemExternalId));

            // Set the EventExternalId - this is an ID that uniquely identifies the audit event in the content source.
            submitContext.CoreMetaData.Add(new SubmissionMetaDataModel(Fields.AuditEvent.EventExternalId, type: nameof(String), value: Guid.NewGuid().ToString()));
            submitContext.CoreMetaData.Add(new SubmissionMetaDataModel(Fields.AuditEvent.EventType, type: nameof(String), value: "Reference Audit Event"));

            submitContext.CoreMetaData.Add(new SubmissionMetaDataModel(Fields.AuditEvent.UserName, type: nameof(String), value: "Record ReferenceConnectorSF"));
            submitContext.CoreMetaData.Add(new SubmissionMetaDataModel(Fields.AuditEvent.UserId, type: nameof(String), value: "Record ReferenceConnectorSF"));
            submitContext.CoreMetaData.Add(new SubmissionMetaDataModel(Fields.AuditEvent.Created, type: nameof(DateTime), value: DateTime.UtcNow.ToString("O")));

            // Set source metadata on the audit event
            submitContext.SourceMetaData.Add(new SubmissionMetaDataModel("Checkin Comments", type: nameof(String), value: "Some checkin comments"));

            // Submit the audit event!
            try
            {
                await _auditEventSubmitPipeline.Submit(submitContext).ConfigureAwait(false);

                HandleSubmitPipelineResult(submitContext);
            }
            catch (Exception)
            {
                // Something went wrong trying to submit the item.
                // Dead-letter the item to a durable data store where it can be retried later. (e.g., a message broker).
            }
        }
Ejemplo n.º 3
0
        private async Task SubmitItem(CancellationToken cancellationToken)
        {
            var submitContext = new SubmitContext
            {
                TenantId                     = _connectorConfigModel.TenantIdAsGuid,
                ConnectorConfigId            = _connectorConfigModel.IdAsGuid,
                ApiClientFactorySettings     = ConnectorApiAuthHelper.GetApiClientFactorySettings(),
                AuthenticationHelperSettings = ConnectorApiAuthHelper.GetAuthenticationHelperSettings(_connectorConfigModel.TenantDomainName),
                CoreMetaData                 = new List <SubmissionMetaDataModel>(),
                SourceMetaData               = new List <SubmissionMetaDataModel>(),
                Filters           = _connectorConfigModel.Filters,
                CancellationToken = cancellationToken
            };

            // Set the "ExternalId" of the item.
            // ExternalId is an ID that uniquely identifies this item in the content source.
            // Multiple submissions of items with the same ExternalId will be treated as different
            // versions of the same item.
            // Submissions of items with different ExternalId values will be treated as different items.
            // In this sample, we generate a new ExternalId for every submission, meaning every submission
            // is a new item.
            var externalId = Guid.NewGuid().ToString();

            submitContext.CoreMetaData.Add(new SubmissionMetaDataModel(Fields.ExternalId, type: nameof(String), value: externalId));

            // Set the "ParentExternalId" of the item.
            // For items this field identifies the parent item.
            var parentExternalId = Guid.NewGuid().ToString();

            submitContext.CoreMetaData.Add(new SubmissionMetaDataModel(Fields.ParentExternalId, type: nameof(String), value: parentExternalId));

            // Set the "SourceLastModifiedDate" of the item.
            // Records365 vNext uses this field to determine ordering of versions of an item. Note that items may be submitted
            // out of order.
            submitContext.CoreMetaData.Add(new SubmissionMetaDataModel(Fields.SourceLastModifiedDate, type: nameof(DateTime), value: DateTime.UtcNow.ToString("O")));

            // Set some mandatory core fields that are required by all items.
            submitContext.CoreMetaData.Add(new SubmissionMetaDataModel(Fields.Title, type: nameof(String), value: $"Fake Record from {_connectorConfigModel.Id}"));
            submitContext.CoreMetaData.Add(new SubmissionMetaDataModel(Fields.Author, type: nameof(String), value: "Record ReferenceConnectorSF"));
            submitContext.CoreMetaData.Add(new SubmissionMetaDataModel(Fields.SourceCreatedDate, type: nameof(DateTime), value: DateTime.UtcNow.ToString("O")));
            submitContext.CoreMetaData.Add(new SubmissionMetaDataModel(Fields.SourceCreatedBy, type: nameof(String), value: "ReferenceConnectorSF"));
            submitContext.CoreMetaData.Add(new SubmissionMetaDataModel(Fields.SourceLastModifiedBy, type: nameof(String), value: "ReferenceConnectorSF"));
            submitContext.CoreMetaData.Add(new SubmissionMetaDataModel(Fields.Location, type: nameof(String), value: "Fake record"));
            submitContext.CoreMetaData.Add(new SubmissionMetaDataModel(Fields.MediaType, type: nameof(String), value: "Electronic"));
            submitContext.CoreMetaData.Add(new SubmissionMetaDataModel(Fields.ContentVersion, type: nameof(String), value: "1.0"));

            // Set some source metadata fields.
            // Source metadata fields are intended for any metadata related to the item available from the content source that is
            // not directly captured by the core metadata. Records365 vNext makes no assumption about the presence or nature of any
            // source metadata. Any source field submitted to Records365 vNext is visible in the UI and is searchable by users.
            submitContext.SourceMetaData.Add(new SubmissionMetaDataModel("Checkin Comments", type: nameof(String), value: "Some checkin comments"));
            submitContext.SourceMetaData.Add(new SubmissionMetaDataModel("Last Sync Date", type: nameof(DateTime), value: DateTime.UtcNow.ToString("O")));
            submitContext.SourceMetaData.Add(new SubmissionMetaDataModel("NumberValue", type: nameof(Double), value: "100"));
            submitContext.SourceMetaData.Add(new SubmissionMetaDataModel("BoolValue", type: nameof(Boolean), value: "true"));

            // Submit the item!
            try
            {
                await _itemSubmitPipeline.Submit(submitContext).ConfigureAwait(false);

                HandleSubmitPipelineResult(submitContext);
            }
            catch (Exception)
            {
                // Something went wrong trying to submit the item.
                // Dead-letter the item to a durable data store where it can be retried later. (e.g., a message broker).
            }

            //If filtered out or otherwise skipped, we do not wish to trigger the following consequential submissions.
            //Note that this may be done as part of HandleSubmitPipelineResult for neater code.
            if (submitContext.SubmitResult.SubmitStatus == SubmitResult.Status.OK)
            {
                // After submitting, check to see if Records365 vNext has a record of the parent item that was referenced
                // in the submission above. If it doesn't, we need to submit it.
                if (submitContext.AggregationFoundDuringItemSubmission.HasValue &&
                    !submitContext.AggregationFoundDuringItemSubmission.Value)
                {
                    await SubmitAggregation(parentExternalId, cancellationToken).ConfigureAwait(false);
                }

                // Submit an audit event for the item.
                await SubmitAuditEvent(externalId, cancellationToken).ConfigureAwait(false);

                // Submit the binary for the item.
                await SubmitBinary(externalId, cancellationToken).ConfigureAwait(false);
            }
        }
Ejemplo n.º 4
0
        private async Task SubmitBinary(string itemExternalId, CancellationToken cancellationToken)
        {
            BinarySubmitContext binarySubmitContext = null;

            // Submit the binary!
            // Note the retry loop here - the binary submission endpoint may reject the submission
            // of a binary if the item it refers to has not been processed by the platform yet.
            int tryCount = 0;

            do
            {
                tryCount++;

                if (binarySubmitContext == null)
                {
                    binarySubmitContext = new BinarySubmitContext
                    {
                        TenantId                     = _connectorConfigModel.TenantIdAsGuid,
                        ConnectorConfigId            = _connectorConfigModel.IdAsGuid,
                        ApiClientFactorySettings     = ConnectorApiAuthHelper.GetApiClientFactorySettings(),
                        AuthenticationHelperSettings = ConnectorApiAuthHelper.GetAuthenticationHelperSettings(_connectorConfigModel.TenantDomainName),
                        CoreMetaData                 = new List <SubmissionMetaDataModel>(),
                        SourceMetaData               = new List <SubmissionMetaDataModel>(),
                        Filters           = _connectorConfigModel.Filters,
                        CancellationToken = cancellationToken
                    };

                    // Associate the binary with the item with the ItemExternalId field.
                    binarySubmitContext.ItemExternalId = itemExternalId;

                    // Set the "ExternalId" of the binary. The ExternalId uniquely identifies the binary in the content
                    // source. Note that this is not the same thing as the ExternalId of the item. An item may have
                    // multiple binaries associated with it - if multiple binaries are submitted, end users can download them
                    // as a zipped archive.
                    binarySubmitContext.ExternalId = Guid.NewGuid().ToString();

                    // Set the "FileName" of the binary. This field is optional. When it is provided, end users will
                    // get this filename by default when they download the binary from Records365 vNext.
                    binarySubmitContext.FileName = "file.txt";
                    binarySubmitContext.FileHash = "Optional MD5 Hash here";
                }

                var fileContent = "This is a binary file!";
                var fileBytes   = Encoding.Default.GetBytes(fileContent);
                using (var stream = new MemoryStream(fileBytes))
                {
                    // Set the Stream of the binary. This stream represents the binary content.
                    // Note that the MemoryStream.Position will be moved to the end on each API call
                    // So if the submission needs to be retried, a new stream should be assigned here
                    binarySubmitContext.Stream = stream;

                    try
                    {
                        await _binarySubmitPipeline.Submit(binarySubmitContext).ConfigureAwait(false);

                        HandleSubmitPipelineResult(binarySubmitContext);
                    }
                    catch (Exception)
                    {
                        // Something went wrong trying to submit the item.
                        // Dead-letter the item to a durable data store where it can be retried later. (e.g., a message broker).
                    }

                    // If the submit was deferred by the platform, wait a few seconds and try again.
                    if (binarySubmitContext.SubmitResult.SubmitStatus == SubmitResult.Status.Deferred)
                    {
                        await Task.Delay(TimeSpan.FromSeconds(2)).ConfigureAwait(false);
                    }
                }
            }while (binarySubmitContext.SubmitResult.SubmitStatus == SubmitResult.Status.Deferred && tryCount < 30);
        }