# How to Extend Ossie with New Vendor-Specific Attributes and Extensions

> Extend Ossie's vendor-agnostic core model with proprietary metadata using JSON. Learn how to implement custom extensions and converters for seamless data management.

- Repository: [The Apache Software Foundation/ossie](https://github.com/apache/ossie)
- Tags: how-to-guide
- Published: 2026-07-26

---

**Ossie supports extending its vendor-agnostic core model through a custom extensions mechanism that stores proprietary metadata as JSON within standardized objects, enabling seamless bidirectional conversion via dedicated import/export converters.**

Apache Ossie is designed as a vendor-neutral semantic modeling framework, yet it provides a structured extension pipeline for integrating proprietary attributes without sacrificing interoperability. Understanding the process for extending Ossie with new vendor-specific attributes and extensions allows developers to bridge Ossie's standardized representations with platform-specific implementations while maintaining round-trip fidelity.

## Define a Stable Vendor Identifier

Choose a unique, free-form string (e.g., `MYVENDOR`) to identify your organization across all extension blocks. According to the core specification in [`core-spec/spec.md`](https://github.com/apache/ossie/blob/main/core-spec/spec.md)【/cache/repos/github.com/apache/ossie/main/core-spec/spec.md#L20-L34】, this identifier serves as the namespace for your custom metadata and must remain stable to ensure compatible parsing across converter versions.

## Design the Vendor-Specific JSON Schema

Determine which fields your vendor implementation requires—such as connection parameters, table options, or security policies. The extension data is stored as a JSON string within the `data` property. Reference schemas for existing vendors like Snowflake, Salesforce, and DBT are documented in [`core-spec/spec.md`](https://github.com/apache/ossie/blob/main/core-spec/spec.md)【/cache/repos/github.com/apache/ossie/main/core-spec/spec.md#L90-L108】 to guide your structure.

## Embed Extensions in the Ossie Model

Insert your vendor block under the appropriate hierarchy level: `semantic_model`, `datasets`, `relationships`, `fields`, or `metrics`. The YAML structure follows a consistent pattern across all levels.

```yaml
datasets:
  - name: sales
    source: analytics.public.sales
    fields:
      - name: revenue
        expression:
          dialects:
            - dialect: ANSI_SQL
              expression: revenue
    custom_extensions:
      - vendor_name: MYVENDOR
        data: '{"partition_key":"region","retention_days":30}'

```

## Implement Converter Pairs

Bidirectional conversion requires implementing both export and import logic using Ossie's **CustomExtensionHandler** utilities.

### Export Converter Implementation

During export, extract extensions where `vendor_name` matches your identifier and deserialize the JSON into your vendor's native objects. The generic extraction logic resides in `CustomExtensionHandler.restoreCustomExtensionsAtLevel`【/cache/repos/github.com/apache/ossie/main/converters/salesforce/src/main/java/org/apache/ossie/converter/CustomExtensionHandler.java#L58-L78】, which traverses arrays and matches items by identifier.

```java
private void applyMyVendorExtensions(OsiDataset dataset, Map<String, Object> ossieItem) {
    List<CustomExtension> extensions = parseCustomExtensions(ossieItem);
    extensions.stream()
        .filter(ext -> "MYVENDOR".equals(ext.getVendorName()))
        .findFirst()
        .ifPresent(ext -> {
            MyVendorConfig cfg = jsonMapper.readValue(ext.getData(), MyVendorConfig.class);
            // map cfg fields to the vendor model
            dataset.setPartitionKey(cfg.getPartitionKey());
            dataset.setRetentionDays(cfg.getRetentionDays());
        });
}

```

### Import Converter Implementation

During import, serialize your vendor configuration into JSON and wrap it in a **CustomExtension** object. The symmetric storage logic is implemented in `CustomExtensionHandler.storeUnmappedProperties`【/cache/repos/github.com/apache/ossie/main/converters/salesforce/src/main/java/org/apache/ossie/converter/CustomExtensionHandler.java#L55-L84】.

```java
private void storeMyVendorExtensions(Map<String, Object> ossieItem, MyVendorDataset vendorDs) {
    MyVendorConfig cfg = new MyVendorConfig(vendorDs.getPartitionKey(), vendorDs.getRetentionDays());
    String json = jsonMapper.writeValueAsString(cfg);
    CustomExtension ext = new CustomExtension();
    ext.setVendorName("MYVENDOR");
    ext.setData(json);
    List<CustomExtension> list = parseCustomExtensions(ossieItem);
    list.add(ext);
    ossieItem.put("custom_extensions", list);
}

```

The Polaris converter demonstrates parsing patterns in [`OsiModelParser.java`](https://github.com/apache/ossie/blob/main/OsiModelParser.java)【/cache/repos/github.com/apache/ossie/main/converters/polaris/src/main/java/org/apache/ossie/converter/polaris/OsiModelParser.java#L62-L76】, showing how extensions are extracted from raw YAML into Java objects.

## Validate and Document Your Extension

Update the **Custom Extensions** table in [`core-spec/spec.md`](https://github.com/apache/ossie/blob/main/core-spec/spec.md)【/cache/repos/github.com/apache/ossie/main/core-spec/spec.md#L34-L48】 to register your vendor name and description. Document the mapping workflow in [`converters/README.md`](https://github.com/apache/ossie/blob/main/converters/README.md)【/cache/repos/github.com/apache/ossie/main/converters/README.md#L90-L102】 following the hub-and-spoke pattern described in lines 24-42.

Validate your implementation using the JSON schema in [`core-spec/osi-schema.json`](https://github.com/apache/ossie/blob/main/core-spec/osi-schema.json)【/cache/repos/github.com/apache/ossie/main/core-spec/osi-schema.json】 and the validation script [`validation/validate.py`](https://github.com/apache/ossie/blob/main/validation/validate.py). Create round-trip test cases using the [`examples/tpcds_semantic_model.yaml`](https://github.com/apache/ossie/blob/main/examples/tpcds_semantic_model.yaml) reference model to ensure `custom_extensions` blocks remain intact through conversion cycles.

## Summary

- **Vendor identifiers** must be unique strings defined in [`core-spec/spec.md`](https://github.com/apache/ossie/blob/main/core-spec/spec.md) to prevent collisions.
- **Extension data** is stored as JSON strings within `custom_extensions` arrays at any model level (datasets, fields, metrics, etc.).
- **Bidirectional converters** rely on `CustomExtensionHandler` methods `restoreCustomExtensionsAtLevel` and `storeUnmappedProperties` to handle extraction and serialization.
- **Validation** requires testing against [`osi-schema.json`](https://github.com/apache/ossie/blob/main/osi-schema.json) and verifying round-trip fidelity using the TPC-DS example model.

## Frequently Asked Questions

### Can multiple vendors extend the same Ossie model simultaneously?

Yes. The `custom_extensions` property is an array that can contain multiple vendor blocks. Each extension is keyed by its `vendor_name`, allowing Ossie models to carry proprietary metadata from several platforms simultaneously without conflict.

### Where should custom_extensions be placed in the model hierarchy?

Extensions can be attached at five levels: `semantic_model`, `datasets`, `relationships`, `fields`, or `metrics`. Place extensions at the level corresponding to the granularity of your vendor data—dataset-level configurations belong under `datasets`, while column-specific attributes belong under `fields` within those datasets.

### How does Ossie ensure round-trip fidelity for vendor data?

The extension mechanism stores vendor data as opaque JSON strings that pass through the core model unchanged. Converter implementations using `CustomExtensionHandler` methods ensure that data extracted during export is serialized identically during import, preserving values through `restoreCustomExtensionsAtLevel` and `storeUnmappedProperties` operations.

### What validation is required before submitting a new vendor extension?

Extensions must validate against the JSON schema defined in [`core-spec/osi-schema.json`](https://github.com/apache/ossie/blob/main/core-spec/osi-schema.json) using [`validation/validate.py`](https://github.com/apache/ossie/blob/main/validation/validate.py). Additionally, implementers should create test cases that round-trip a model through their converter, asserting that the `custom_extensions` block in [`examples/tpcds_semantic_model.yaml`](https://github.com/apache/ossie/blob/main/examples/tpcds_semantic_model.yaml) remains unchanged after export and re-import.