Centeva.AdamsInterface 1.0.0

Prefix Reserved
dotnet add package Centeva.AdamsInterface --version 1.0.0
                    
NuGet\Install-Package Centeva.AdamsInterface -Version 1.0.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Centeva.AdamsInterface" Version="1.0.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Centeva.AdamsInterface" Version="1.0.0" />
                    
Directory.Packages.props
<PackageReference Include="Centeva.AdamsInterface" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Centeva.AdamsInterface --version 1.0.0
                    
#r "nuget: Centeva.AdamsInterface, 1.0.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Centeva.AdamsInterface@1.0.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Centeva.AdamsInterface&version=1.0.0
                    
Install as a Cake Addin
#tool nuget:?package=Centeva.AdamsInterface&version=1.0.0
                    
Install as a Cake Tool

Centeva.AdamsInterface

ADAMS API client library for .NET - Supports Windows Authentication, Bearer Token (OIDC), and pluggable authentication strategies for integrating with ADAMS document management systems.

Built With

  • .NET 8.0, .NET 9.0 & .NET 10.0
  • Mediator 3.0.2 - CQRS command/query pattern (replaces MediatR for licensing)
  • FluentValidation 11.11.0 - Request validation with automatic pipeline integration
  • ASP.NET Core - HTTP client and authentication infrastructure

Getting Started

Installation

dotnet add package Centeva.AdamsInterface

Basic Configuration

Windows Authentication (Default)
services.AddAdamsClient(configuration);
Bearer Token / OIDC Authentication
services.AddAdamsClientCore(configuration)
    .AddBearerTokenAuthentication();
Custom Token Provider
services.AddAdamsClientCore(configuration)
    .AddBearerTokenAuthentication(async () => 
    {
        // Your custom token acquisition logic
        return await GetAccessTokenAsync();
    });
No Authentication (Testing/Development)
services.AddAdamsClientCore(configuration)
    .AddNoAuthentication();
With Mediator Commands
services.AddAdamsClientWithMediator(configuration); // Includes Windows Auth + Mediator
// or
services.AddAdamsClient(configuration)
    .AddAdamsMediatorHandlers();

Configuration

Add ADAMS configuration to your appsettings.json:

{
  "AdamsApi": {
    "BaseUrl": "https://your-adams-server/adams/api",
    "Timeout": 120
  }
}

Usage Patterns

This package supports three integration patterns depending on your application architecture. Choose the pattern that best fits your needs:

Use when: Building any application - controllers, services, background jobs

Inject IAdamsApiClient and call methods directly. This is the simplest, most maintainable approach.

Configuration:

services.AddAdamsClient(configuration); // Registers IAdamsApiClient with Windows Auth

In ASP.NET Core Controllers:

using Centeva.AdamsInterface.Entities.Document;
using Centeva.AdamsInterface.Interfaces;
using Microsoft.AspNetCore.Mvc;

public class AdamsDocumentController : ControllerBase
{
    private readonly IAdamsApiClient _adamsClient;

    public AdamsDocumentController(IAdamsApiClient adamsClient)
    {
        _adamsClient = adamsClient;
    }

    [HttpPost("AddNewDraft")]
    public Task<AddNewDraft.Response> AddNewDraft([FromBody] AddNewDraft.Request request)
    {
        return _adamsClient.Document.AddNewDraft(request, HttpContext.RequestAborted);
    }

    [HttpGet("SubmitToDpc")]
    public Task<SubmitToDpcForNormalProcessing.Response> SubmitToDpc(string accessionNumber)
    {
        var request = new SubmitToDpcForNormalProcessing.Request
        {
            AccessionNumber = accessionNumber
        };
        return _adamsClient.Document.SubmitToDpcForNormalProcessing(request, HttpContext.RequestAborted);
    }
}

In Application Services:

using Centeva.AdamsInterface.Interfaces;

public class DocumentService
{
    private readonly IAdamsApiClient _adamsClient;

    public DocumentService(IAdamsApiClient adamsClient)
    {
        _adamsClient = adamsClient;
    }

    public async Task<string> CreateDocumentAsync(string title, string fileUrl)
    {
        var response = await _adamsClient.Document.AddNewDraft(new AddNewDraft.Request
        {
            DocumentTitle = title,
            DocumentPathAndFileName = fileUrl,
            Availability = "Public",
            SensitivityReviewCompleted = "Yes",
            SunsiDocumentSensitivity = "Not Sensitive"
        }, CancellationToken.None);
        
        return response.AccessionNumber;
    }
}

Benefits:

  • ✅ Simplest approach - no mediator framework required
  • ✅ Direct control flow - easy to debug and trace
  • ✅ Zero abstraction overhead
  • ✅ Entity Request objects have built-in FluentValidation
  • ✅ No command wrapper duplication across consuming apps

Pattern 2: Mediator Commands (For CQRS Architectures)

Use when: Your application uses Mediator.SourceGenerator and you want CQRS pattern consistency

Use the package's 43 built-in Mediator command handlers to integrate with your existing Mediator pipeline.

Configuration:

services.AddMediator(); // Your app's Mediator configuration
services.AddAdamsMediatorHandlers(); // Registers package's command handlers

Usage:

using Centeva.AdamsInterface.Commands.Document;
using Centeva.AdamsInterface.Entities.Document;

public class DocumentController : ControllerBase
{
    private readonly Mediator.IMediator _mediator;
    
    public DocumentController(Mediator.IMediator mediator)
    {
        _mediator = mediator;
    }
    
    [HttpPost("AddNewDraft")]
    public Task<AddNewDraft.Response> AddNewDraft([FromBody] AddNewDraft.Request request)
    {
        return _mediator.Send(new AddNewDraftCommand.Request(request));
    }
}

Benefits:

  • ✅ Integrates with existing Mediator pipeline and behaviors
  • ✅ Reuses package's FluentValidation rules automatically
  • ✅ Consistent CQRS pattern throughout your application

Pattern 3: Custom Orchestration Commands

Use when: Creating application-specific workflows that coordinate multiple ADAMS operations or integrate with your domain logic

For complex workflows that go beyond simple API calls, create custom commands that orchestrate multiple operations.

using Centeva.AdamsInterface.Interfaces;
using MediatR; // or Mediator

public class UploadDocumentPackageCommand : IRequest<UploadResult>
{
    public int DocumentId { get; set; }
    public List<FileInfo> Files { get; set; }
    public string PackageTitle { get; set; }
}

public class Handler : IRequestHandler<UploadDocumentPackageCommand, UploadResult>
{
    private readonly IAdamsApiClient _adamsClient;
    private readonly IRepository _repository;
    private readonly IStorageService _storage;

    public async Task<UploadResult> Handle(UploadDocumentPackageCommand command, CancellationToken ct)
    {
        // 1. Your business logic: Upload files to storage
        var fileUrls = await _storage.UploadFilesAsync(command.Files);

        // 2. ADAMS API: Create package
        var packageResponse = await _adamsClient.Package.AddNewPackage(new AddNewPackage.Request
        {
            PackageTitle = command.PackageTitle,
            Availability = "Public"
        }, ct);

        // 3. ADAMS API: Add documents to package
        foreach (var url in fileUrls)
        {
            var docResponse = await _adamsClient.Document.AddNewDraft(new AddNewDraft.Request
            {
                DocumentPathAndFileName = url,
                DocumentTitle = $"Document {Path.GetFileName(url)}"
            }, ct);

            await _adamsClient.Package.FileIntoPackage(new FileIntoPackage.Request
            {
                DocumentAccessionNumber = docResponse.AccessionNumber,
                PackageAccessionNumber = packageResponse.AccessionNumber
            }, ct);
        }

        // 4. Your business logic: Update database
        await _repository.SaveAccessionNumber(command.DocumentId, packageResponse.AccessionNumber);

        return new UploadResult { AccessionNumber = packageResponse.AccessionNumber };
    }
}

This is NOT duplication because it:

  • Orchestrates multiple ADAMS API calls
  • Integrates with your domain (database, business rules)
  • Coordinates with other services (storage, notifications)
  • Contains application-specific workflow logic

DO NOT create simple command wrappers that just forward to IAdamsApiClient - use Pattern 1 (direct API client) instead.

ADAMS Upload Workflow Pattern

Note: The ADAMS service currently uses Azure Blob Storage as the file storage location for document uploads. When uploading documents, you'll need to provide URLs to files stored in Azure Blob Storage.

The typical workflow for uploading documents to ADAMS involves multiple steps. Here's the recommended pattern:

1. Upload Files to Your Storage

// Upload file to your storage system (Azure Blob, AWS S3, file system, etc.)
var fileUrl = await _storageService.UploadFileAsync(fileStream, fileName);

2. Create ADAMS Folder

var folderResponse = await _adamsClient.Folder.AddNewFolderAsync(new AddNewFolderRequest
{
    Title = "Project Documents",
    FolderType = "ProjectFolder"
});
var folderId = folderResponse.FolderId;

3. Create Package (Optional)

var packageResponse = await _adamsClient.Package.AddNewPackageAsync(new AddNewPackageRequest
{
    PackageTitle = "Document Package",
    // ... other properties
});
var packageId = packageResponse.PackageId;

4. Add Documents to ADAMS

var documentResponse = await _adamsClient.Document.AddNewDraftAsync(new AddNewDraftRequest
{
    Title = fileName,
    DocumentType = "Report",
    FileLocation = fileUrl, // URL from your storage system
    // ... other properties
});
var accessionNumber = documentResponse.AccessionNumber;

5. File Documents into Folder/Package

// File into folder
await _adamsClient.Document.FileIntoFolderAsync(new FileIntoFolderRequest
{
    AccessionNumber = accessionNumber,
    FolderId = folderId
});

// Or file into package
await _adamsClient.Document.FileIntoPackageAsync(new FileIntoPackageRequest
{
    AccessionNumber = accessionNumber,
    PackageId = packageId
});

6. Store Accession Numbers

// Store the ADAMS accession number in your application database
await _repository.UpdateDocumentAsync(documentId, accessionNumber);

7. Submit to DPC (If Required)

await _adamsClient.Document.SubmitToDpcAsync(new SubmitToDpcRequest
{
    AccessionNumber = accessionNumber
});

Authentication Strategies

Note: The ADAMS service currently uses Windows Authentication with Kerberos delegation. The ADAMS team is actively working on implementing OIDC authentication support, which will be available in a future release.

Windows Authentication with Kerberos Delegation

The WindowsAuthenticationStrategy uses WindowsIdentity.RunImpersonatedAsync to perform Kerberos delegation, allowing the ADAMS API calls to run under the authenticated user's context:

services.AddAdamsClient(configuration); // Default Windows Auth

Requirements:

  • Windows Server environment
  • Kerberos configured for delegation
  • Application pool configured for Windows Authentication

Bearer Token Authentication

The BearerTokenAuthenticationStrategy supports OIDC/OAuth2 token-based authentication:

// Token from Authorization header
services.AddAdamsClientCore(configuration)
    .AddBearerTokenAuthentication();

// Token from custom provider
services.AddAdamsClientCore(configuration)
    .AddBearerTokenAuthentication(async () => await GetTokenAsync());

Token Resolution Order:

  1. Custom token provider (if configured)
  2. Authorization: Bearer {token} header
  3. access_token user claim

No Authentication Strategy

For testing and development environments:

services.AddAdamsClientCore(configuration)
    .AddNoAuthentication();

Running Tests

dotnet test

Contributing

  1. Follow Centeva coding standards (file-scoped namespaces, nullable reference types enabled)
  2. Maintain XML documentation comments for public APIs
  3. Add unit tests for new features
  4. Ensure all tests pass before submitting PRs
  5. Follow semantic versioning for releases

License

This project is licensed under the MIT License - see the LICENSE file for details.

Platform Compatibility

  • Windows Authentication: Windows only (uses WindowsIdentity.RunImpersonatedAsync)
  • Bearer Token Authentication: Cross-platform (Windows, Linux, macOS)
  • No Authentication: Cross-platform

Dependency Notes

  • Mediator: Uses Mediator.SourceGenerator (MIT license) instead of MediatR to avoid commercial licensing
  • FluentValidation: Automatically integrated into Mediator pipeline when using AddAdamsMediatorHandlers()
  • Entity Framework Core: Used for domain modeling, not for database access in this library
  • ASP.NET Core MVC: Required only for SimulatedAdams test controllers
Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.0 47 5/28/2026