Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Table of Contents
stylenone

Required Headers

  1. Authorization: Bearer <your_auth_token>

  2. Content-Type: application/json

  3. X-File-Content-Classification: Insights.UnityProjects

  4. X-File-Content-Length: <original_file_size_in_bytes>

  5. X-File-Content-MD5: <MD5_hash_of_original_file>

  6. X-File-Name: <original_file_name.json>

Valid Header Values

  • X-File-Content-Classification: Insights.UnityProjects - A classification to help us track the source of this data.

  • X-File-Content-Length: A positive integer representing the size of the original (uncompressed) JSON file in bytes

  • X-File-Content-MD5: The MD5 hash of the original (uncompressed) JSON file

  • X-File-Name: The original filename of your JSON file

Overview

The File Upload API enables secure transmission of structured data files to our platform. It supports various file formats including JSON, CSV, XML, and YAML in both raw and compressed (gzip) formats. This API is designed for data migration and integration, providing an efficient pathway for transferring data into our system.

API Endpoint

Code Block
POST https://api.[opsera-org].opsera.io/data-migration-file/data/upload

Opsera API Token Generation

From within the Opsera portal, follow these steps to generate an API token if you don't already have one.

...

For more information please see: https://docs.opsera.io/api-platform-and-integration/opsera-api-platform/personal-access-tokens

Steps to Test Using cURL

  1. Prepare your JSON file (e.g., "data.json").

  2. Calculate the MD5 hash and file size of the original JSON file:

Code Block
   original_md5=$(md5sum data.json | cut -d ' ' -f 1)
   original_size=$(wc -c < data.json)
  1. Use the following curl command to upload the file (replace placeholders with your actual values):

...

Authentication

All requests require authentication using a bearer token.

  1. Obtain an API token from the Opsera portal

  2. Include the token in the Authorization header

    Code Block
    Authorization: Bearer <your_token>

Required Headers

Header

Description

Required

Example

Authorization

Bearer token for authentication

Yes

Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

Content-Type

Media type of the file being uploaded

Yes

application/json

X-File-Content-Length

Size of the file in bytes

Yes

42768

X-File-Content-MD5

MD5 hash of the file for integrity verification

Yes

d41d8cd98f00b204e9800998ecf8427e

X-File-Name

Name of the file being uploaded

Yes

project_data.json

X-File-Content-Classification

Classification category for the uploaded content

Yes

Insights.UnityProjects

Content-Encoding

Encoding of the file content (for compressed files)

Only for compressed files

gzip

Content Classification

The X-File-Content-Classification header specifies the category of data being uploaded. Please contact your Opsera account representative for the appropriate classification value for your use case.

Supported File Types

File Type

Content-Type Header

JSON

application/json

CSV

text/csv or application/csv

XML

text/xml or application/xml

YAML

application/yaml or application/x-yaml

Gzipped JSON

application/json with Content-Encoding: gzip

Gzipped CSV

text/csv with Content-Encoding: gzip

Gzipped XML

application/xml with Content-Encoding: gzip

Gzipped YAML

application/yaml with Content-Encoding: gzip

Request Body

The request body should contain the raw file content as binary data.

File Validation

The API performs the following validations:

  1. The content type is checked against supported formats

  2. The file size is validated against the provided X-File-Content-Length

  3. The MD5 hash is verified against the provided X-File-Content-MD5

  4. The file content is validated for correctness based on the content type

Response

A successful upload will return a 200 OK response with the following JSON structure:

Code Block
languagejson
{   
  "id": "artifactId",   
  "contentLength": 42768,   
  "contentMD5": "d41d8cd98f00b204e9800998ecf8427e" 
}

Description of Response Attributes

  • id: A string representing the unique identifier (artifactId) assigned to the uploaded file. This ID can be used for future references or operations related to this file.

  • contentLength: A number indicating the size of the original (uncompressed) file in bytes. This should match the value you provided in the X-File-Content-Length header.

  • contentMD5: A string containing the MD5 hash of the original (uncompressed) file. This should match the value you provided in the X-File-Content-MD5 header.

Error Codes

Status

Description

200

Successful upload

400

Bad request - invalid content type, content length, MD5, or payload

403

Forbidden - invalid authentication

500

Server error

Examples

Uploading a JSON File

Code Block
languagebash
curl -X POST "https://api.opsera-test.opsera.io/data-migration-file/data/upload" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -H "X-File-Content-Classification: Insights.UnityProjects" \
  -H "X-File-Content-Length: 2048" \
  -H "X-File-Content-MD5: b5d4ee21f9d850e1358744c1ea0434bb" \
  -H "X-File-Name: project_data.json" \
  --data-binary "@/path/to/project_data.json"

Uploading a CSV File

Code Block
languagebash
curl -X POST "https://api.opsera-test.opsera.io/data-migration-file/data/upload" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: text/csv" \
  -H "X-File-Content-Classification: Insights.UnityProjects" \
  -H "X-File-Content-Length: 1536" \
  -H "X-File-Content-MD5: 7a11e1cadbcd6c44c7a2d20fd440c1b0" \
  -H "X-File-Name: metrics.csv" \
  --data-binary "@/path/to/metrics.csv"

Uploading a Compressed JSON File

Code Block
languagebash
curl -X POST "https://api.honeywellopsera-sandboxtest.opsera.io/data-migration-file/data/upload" \
     -H "Authorization: Bearer YOUR_AUTHAPI_TOKEN" \
     -H "Content-Type: application/json" \
  -H "Content-Encoding: gzip" \
     -H "X-File-Content-Classification: Insights.UnityProjects" \
     -H "X-File-Content-Length: $original_size4096" \
       # Original uncompressed size
  -H "X-File-Content-MD5: $original_md5a3e75a566f32c4d542c9f71a15c15a6c" \
       # MD5 of uncompressed content
  -H "X-File-Name: datalarge_dataset.json.gz" \
     --data-binary "@data@/path/to/large_dataset.json.gz"

Expected API Response

...

Code Block
{
  "id": "string",
  "contentLength": number,
  "contentMD5": "string"
}

Description of Response Attributes

  • id: A string representing the unique identifier (artifactId) assigned to the uploaded file. This ID can be used for future references or operations related to this file.

  • contentLength: A number indicating the size of the original (uncompressed) file in bytes. This should match the value you provided in the X-File-Content-Length header.

  • contentMD5: A string containing the MD5 hash of the original (uncompressed) file. This should match the value you provided in the X-File-Content-MD5 header.

Example Response

Code Block
❯ export AUTH_TOKEN="{auth token}"

❯ ./testGzippedJSONFileUpload.sh
Original JSON file size:  17934041
Original JSON file MD5 hash: d5ce63f2310d40ce14d7044764725e1a
Gzipped file size:   970511
Gzipped file MD5 hash: 1a0f877a9efb97d010d52155e0dd3778
Sending file: HCE-full.json.gz
Content-Length:   970511
X-File-Content-Length:  17934041
X-File-Content-MD5: d5ce63f2310d40ce14d7044764725e1a
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  947k  100   106  100  947k     40   363k  0:00:02  0:00:02 --:--:--  363k
Response status code: 0
Response body:
{"id":"66cd1b866f255a5904fffed9","contentLength":17934041,"contentMD5":"d5ce63f2310d40ce14d7044764725e1a"}
ID: 66cd1b866f255a5904fffed9
Expected File Size: 17934041
Expected MD5: d5ce63f2310d40ce14d7044764725e1a
Upload successful!

...

Uploading a Compressed CSV File

Code Block
languagebash
curl -X POST "https://api.opsera-test.opsera.io/data-migration-file/data/upload" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: text/csv" \
  -H "Content-Encoding: gzip" \
  -H "X-File-Content-Classification: Insights.UnityProjects" \
  -H "X-File-Content-Length: 3072" \  # Original uncompressed size
  -H "X-File-Content-MD5: 1f4e6b8a2d0c3f5e7a9b1c8d2e5f6a7b" \  # MD5 of uncompressed content
  -H "X-File-Name: historical_data.csv.gz" \
  --data-binary "@/path/to/historical_data.csv.gz"

Important Notes for All Uploads

  1. The X-File-Content-Length header should represent the size in bytes of the original file content

  2. The X-File-Content-MD5 should be the MD5 hash of the original file content

  3. For compressed files, these values should represent the uncompressed data

Important Notes for Compressed Files

When uploading compressed files:

  1. The Content-Type header should reflect the type of the uncompressed content (e.g., application/json for a gzipped JSON file)

  2. Always include the Content-Encoding: gzip header

  3. X-File-Content-Length should be the size of the original uncompressed file

  4. X-File-Content-MD5 should be the MD5 hash of the original uncompressed content

Sample Code

Node.js Example

Code Block
languagejs
const axios = require('axios');
const fs = require('fs');
const crypto = require('crypto');
const zlib = require('zlib');

async function uploadFile(filePath, apiToken, isCompressed = false) {
  // Read file content
  const fileContent = fs.readFileSync(filePath);
  const fileName = filePath.split('/').pop();
  
  // Determine if we need to compress the data
  let uploadContent = fileContent;
  let originalContent = fileContent;
  
  if (isCompressed) {
    // If we're uploading a pre-compressed file, decompress it for MD5 calculation
    if (fileName.endsWith('.gz')) {
      originalContent = zlib.gunzipSync(fileContent);
    } else {
      // Compress the file for upload
      uploadContent = zlib.gzipSync(fileContent);
      originalContent = fileContent;
    }
  }
  
  // Calculate MD5 hash of the original (uncompressed) content
  const md5Hash = crypto.createHash('md5').update(originalContent).digest('hex');
  
  // Determine content type based on file extension
  let contentType;
  if (fileName.endsWith('.json') || fileName.endsWith('.json.gz')) {
    contentType = 'application/json';
  } else if (fileName.endsWith('.csv') || fileName.endsWith('.csv.gz')) {
    contentType = 'text/csv';
  } else if (fileName.endsWith('.xml') || fileName.endsWith('.xml.gz')) {
    contentType = 'application/xml';
  } else if (fileName.endsWith('.yaml') || fileName.endsWith('.yml') || 
             fileName.endsWith('.yaml.gz') || fileName.endsWith('.yml.gz')) {
    contentType = 'application/yaml';
  }
  
  // Set headers
  const headers = {
    'Authorization': `Bearer ${apiToken}`,
    'Content-Type': contentType,
    'X-File-Content-Classification': 'Insights.UnityProjects',
    'X-File-Content-Length': originalContent.length.toString(),
    'X-File-Content-MD5': md5Hash,
    'X-File-Name': fileName
  };
  
  // Add Content-Encoding header for compressed uploads
  if (isCompressed || fileName.endsWith('.gz')) {
    headers['Content-Encoding'] = 'gzip';
  }
  
  try {
    // Upload file
    const response = await axios.post(
      'https://api.opsera-test.opsera.io/data-migration-file/data/upload',
      uploadContent,
      { headers }
    );
    
    console.log('Upload successful:', response.data);
    return response.data;
  } catch (error) {
    console.error('Upload failed:', error.response ? error.response.data : error.message);
    throw error;
  }
}

// Example usage
uploadFile('./data/project_data.json', 'YOUR_API_TOKEN', false)
  .then(result => console.log('Done!'))
  .catch(err => console.error('Error:', err));

Getting Help

If you encounter any issues not covered in this documentation, please contact our support team or open a ticket in the customer support portal.