An open-source application that transforms EPCIS documents from XML to JSON/JSON-LD format quickly and effortlessly. Visit openepcis.io to find more usesul resources on EPCIS and EPCIS 2.0 Linked Data. Another documentation page is available from https://openepcis.io/docs/format-converter/.
- Introduction
- Project Modules And Artifacts
- Getting Started
- All-In-One Tools Docker Image
- How To Get In Contact and Contribute
The supply chain system, whether comprising a single organization or multiple entities, plays a crucial role in delivering products or services to clients or consumers. All physical and digital products undergo various supply chain activities before reaching customers. Ensuring accessibility and visibility of product data throughout its life cycle in the supply chain is essential for tracking products in real-time and communicating relevant information to customers or other organizations.
EPCIS (Electronic Product Code Information Services) is a standard developed by ISO (International Organization for Standardization), IEC (International Electrotechnical Commission), and GS1. It facilitates the generation and exchange of visibility data within and across organizations based on business context. Since its initial release in 2007, EPCIS has seen several updates, with versions 1.1 and 1.2 released in 2014 and 2016, respectively. The latest version, EPCIS 2.0, introduces several enhancements, including support for JSON/JSON-LD formats in addition to XML.
EPCIS is a global standard adopted by diverse business sectors, including automotive, food, healthcare, retail, and more. With EPCIS 2.0 supporting both XML and JSON-LD formats, there is a growing need to convert large EPCIS event documents between these formats. This conversion facilitates data exchange, standardization across applications, and other operational conveniences.
While there are existing open-source tools for format conversion, they often fall short in reliably converting typical EPCIS events. Specific properties, such as userExtensions
and sensorElements
, along with various attributes, require careful handling to ensure compliance with standards during conversion. Currently, no tool effectively and efficiently handles bulk EPCIS event document conversion between XML and JSON-LD formats.
Our application aims to fill this gap by providing a reliable solution for converting EPCIS events between formats. It is designed to handle large volumes of data efficiently, ensuring compliance with EPCIS 2.0 standards. Regardless of industry, use case, or supply chain system, our application offers a streamlined solution for transforming EPCIS events.
- Bulk Conversion: Efficiently converts large EPCIS event documents between XML and JSON-LD formats.
- Standards Compliance: Ensures all converted events adhere to EPCIS 2.0 standards.
- Versatile Application: Suitable for various industries and supply chain systems.
- User-Friendly Interface: Simplifies the conversion process for users.
- GraalVM-Community Native Builds: Provides binary executable artifacts for Linux, macOS, and Windows, supporting both amd64 and arm64 architectures.
By providing a robust and efficient EPCIS event format converter, we aim to support the EPCIS community and facilitate smoother data exchanges across different platforms.
The openepcis-document-converter
project is composed of several modules, each serving a distinct purpose in the overall functionality of converting EPCIS event documents. Below is a brief description of each module:
- core: This module contains the core functionality for converting EPCIS event documents between XML and JSON/JSON-LD formats, as well as converting EPCIS 1.2 XML documents to EPCIS 2.0 XML documents and vice versa.
- quarkus/runtime: Provides runtime support for the document conversion processes within the Quarkus framework.
- quarkus/deployment: Handles the deployment-specific configurations and optimizations for running the converter on the Quarkus platform.
- service/converter-service-restassured: Contains integration tests for the REST service using RestAssured to ensure the reliability and correctness of the conversion services.
- service/converter-service-rest: Implements the RESTful web service interface for the document converter, allowing for remote invocation and interaction.
- service/converter-service-servlet: Provides a servlet-based interface for the document converter, enabling web-based interaction.
- service/quarkus-converter-service: This module creates the executable artifacts, resulting in a fully functional REST application. It includes Swagger UI and all necessary components for deploying the converter in a microservice or cloud environment.
This project relies on a series of dependencies managed centrally to ensure consistency across all modules. Key dependencies include:
- io.openepcis.quarkus:quarkus-openepcis-model: The model classes for EPCIS entities within the Quarkus framework.
- io.openepcis.quarkus:quarkus-openepcis-model-deployment: Deployment-specific configurations for the EPCIS model in Quarkus.
- xalan:xalan and xalan:serializer: Libraries for XML processing and transformation.
- io.openepcis:openepcis-epc-digitallink-translator: Utilities for converting EPC identifiers between URN and WebURI formats.
- io.openepcis:openepcis-repository-common: Common repository utilities supporting URN to WebURI conversions.
- io.openepcis:openepcis-test-resources: Test resources for ensuring the quality and correctness of the conversion logic.
The project uses repositories from Sonatype for managing dependencies. The snapshot repository is configured to receive frequent updates, ensuring that the latest development versions are always available:
- sonatype-staging: Sonatype Snapshots (https://s01.oss.sonatype.org/content/repositories/snapshots) with snapshot updates enabled. Snapshots will be created on a frequent basis to provide the latest features and fixes.
This section provides instructions for running the openepcis-document-converter
using Docker and Podman. We provide two Docker images:
ghcr.io/openepcis/quarkus-converter-service:latest
ghcr.io/openepcis/quarkus-converter-service-native:latest
(native executable)
Both images are multiarch and support amd64
and arm64
.
We offer a native Docker image to provide an optimized experience for our users. On a typical machine, starting the application in JVM mode takes around 2000ms, while the native version starts up in just under 100ms. Although the JVM may show improved performance over extended periods, the native image boasts a significantly faster startup time. This rapid startup is essential in cloud environments, particularly when targeting serverless architectures, where quick scaling and responsiveness are critical. The native Docker image ensures your applications are ready to handle requests almost instantly, enhancing efficiency and performance in dynamic cloud setups.
To run the quarkus-converter-service
using Docker, follow these steps:
-
Pull the Docker image:
For the standard executable:
docker pull ghcr.io/openepcis/quarkus-converter-service:latest
For the native executable:
docker pull ghcr.io/openepcis/quarkus-converter-service-native:latest
-
Run the Docker container:
For the standard executable:
docker run --rm -ti -p 8080:8080 -p 8443:8443 ghcr.io/openepcis/quarkus-converter-service:latest
For the native executable:
docker run --rm -ti -p 8080:8080 -p 8443:8443 ghcr.io/openepcis/quarkus-converter-service-native:latest
-p 8080:8080
maps port 8080 for HTTP access.-p 8443:8443
maps port 8443 for HTTPS access with a self-signed certificate.
To run the quarkus-converter-service
using Podman, follow these steps:
-
Pull the Podman image:
For the standard executable:
podman pull ghcr.io/openepcis/quarkus-converter-service:latest
For the native executable:
podman pull ghcr.io/openepcis/quarkus-converter-service-native:latest
-
Run the Podman container:
For the standard executable:
podman run --rm -ti -p 8080:8080 -p 8443:8443 ghcr.io/openepcis/quarkus-converter-service:latest
For the native executable:
podman run --rm -ti -p 8080:8080 -p 8443:8443 ghcr.io/openepcis/quarkus-converter-service-native:latest
-p 8080:8080
maps port 8080 for HTTP access.-p 8443:8443
maps port 8443 for HTTPS access with a self-signed certificate.
The application includes Swagger UI for API documentation and testing, accessible at:
Following section provides quick overview of how to convert the EPCIS document from one format to another:
Our Swagger UI comes pre-loaded with practical examples to help you get started quickly. These examples demonstrate various use cases and API interactions, providing a hands-on way to understand and utilize the converter's capabilities. You can easily access and experiment with these examples directly within the Swagger UI interface.
In addition to the examples available in Swagger UI, here are some more direct cURL examples.
curl -X 'POST' \
'http://localhost:8080/api/convert/xml/2.0' \
-H 'accept: application/xml' \
-H 'Content-Type: application/ld+json' \
-d '{
"@context": ["https://ref.gs1.org/standards/epcis/2.0.0/epcis-context.jsonld"],
"type": "EPCISDocument",
"schemaVersion": "2.0",
"creationDate":"2019-11-01T14:00:00.000+01:00",
"epcisBody": {
"eventList": [
{
"type": "AssociationEvent",
"eventTime": "2019-11-01T14:00:00.000+01:00",
"eventTimeZoneOffset": "+01:00",
"parentID":"urn:epc:id:grai:4012345.55555.987",
"childEPCs":["urn:epc:id:giai:4000001.12345"],
"action": "ADD",
"bizStep": "assembling",
"readPoint": {"id": "urn:epc:id:sgln:4012345.00001.0"}
}
]
}
}'
curl -X 'POST' \
'http://localhost:8080/api/convert/xml/2.0' \
-H 'accept: application/xml' \
-H 'Content-Type: application/ld+json' \
-H 'GS1-EPC-Format: Always_GS1_Digital_Link' \
-d '{
"@context": ["https://ref.gs1.org/standards/epcis/2.0.0/epcis-context.jsonld"],
"type": "EPCISDocument",
"schemaVersion": "2.0",
"creationDate":"2019-11-01T14:00:00.000+01:00",
"epcisBody": {
"eventList": [
{
"type": "AssociationEvent",
"eventTime": "2019-11-01T14:00:00.000+01:00",
"eventTimeZoneOffset": "+01:00",
"parentID":"urn:epc:id:grai:4012345.55555.987",
"childEPCs":["urn:epc:id:giai:4000001.12345"],
"action": "ADD",
"bizStep": "assembling",
"readPoint": {"id": "urn:epc:id:sgln:4012345.00001.0"}
}
]
}
}'
curl -X 'POST' \
'http://localhost:8080/api/convert/xml/2.0' \
-H 'accept: application/xml' \
-H 'Content-Type: application/ld+json' \
-H 'GS1-CBV-XML-Format: Always_Web_URI' \
-H 'GS1-EPC-Format: Always_GS1_Digital_Link' \
-d '{
"@context": ["https://ref.gs1.org/standards/epcis/2.0.0/epcis-context.jsonld"],
"type": "EPCISDocument",
"schemaVersion": "2.0",
"creationDate":"2019-11-01T14:00:00.000+01:00",
"epcisBody": {
"eventList": [
{
"type": "AssociationEvent",
"eventTime": "2019-11-01T14:00:00.000+01:00",
"eventTimeZoneOffset": "+01:00",
"parentID":"urn:epc:id:grai:4012345.55555.987",
"childEPCs":["urn:epc:id:giai:4000001.12345"],
"action": "ADD",
"bizStep": "assembling",
"readPoint": {"id": "urn:epc:id:sgln:4012345.00001.0"}
}
]
}
}'
curl -X 'POST' \
'http://localhost:8080/api/convert/xml/1.2' \
-H 'accept: application/xml' \
-H 'Content-Type: application/ld+json' \
-H 'GS1-CBV-XML-Format: Always_URN' \
-H 'GS1-EPC-Format: Always_EPC_URN' \
-d '{
"@context": ["https://ref.gs1.org/standards/epcis/2.0.0/epcis-context.jsonld"],
"type": "EPCISDocument",
"schemaVersion": "2.0",
"creationDate":"2019-11-01T14:00:00.000+01:00",
"epcisBody": {
"eventList": [
{
"type": "AssociationEvent",
"eventTime": "2019-11-01T14:00:00.000+01:00",
"eventTimeZoneOffset": "+01:00",
"parentID":"https://id.gs1.org/8003/4012345555554987",
"childEPCs":["https://id.gs1.org/8004/400000112345"],
"action": "ADD",
"bizStep": "assembling",
"readPoint": {"id": "https://id.gs1.org/414/4012345000016"}
}
]
}
}'
curl -X 'POST' \
'http://localhost:8080/api/convert/json/2.0' \
-H 'accept: application/ld+json' \
-H 'Content-Type: application/xml' \
-H 'GS1-EPC-Format: Always_GS1_Digital_Link' \
-d '<?xml version="1.0" encoding="UTF-8"?><epcis:EPCISDocument xmlns:epcis="urn:epcglobal:epcis:xsd:1" xmlns:xalan="http://xml.apache.org/xslt" schemaVersion="1.2" creationDate="2019-11-01T14:00:00.000+01:00">
<EPCISBody>
<EventList>
<extension>
<extension>
<AssociationEvent>
<eventTime>2019-11-01T14:00:00+01:00</eventTime>
<eventTimeZoneOffset>+01:00</eventTimeZoneOffset>
<parentID>urn:epc:id:grai:4012345.55555.987</parentID>
<childEPCs>
<epc>urn:epc:id:giai:4000001.12345</epc>
</childEPCs>
<action>ADD</action>
<bizStep>urn:epcglobal:cbv:bizstep:assembling</bizStep>
<readPoint>
<id>urn:epc:id:sgln:4012345.00001.0</id>
</readPoint>
</AssociationEvent>
</extension>
</extension>
</EventList>
</EPCISBody>
</epcis:EPCISDocument>'
In order not to bloat up this README we have added a few more examples:
If you have a EPCIS 2.0 XML document which you want to convert to JSON/JSON-LD then provide it as InputStream
to convert method of XmlToJsonConverter.class:
final ByteArrayOutputStream jsonOutput = new ByteArrayOutputStream();
final EventJSONStreamCollector collector = new EventJSONStreamCollector(jsonOutput);
final EventHandler handler = new EventHandler(new EventValidator(), collector);
new XmlToJsonConverter().convert(xmlStream, handler);
System.out.println(jsonOutput.toString());
If you have a EPCIS 2.0 JSON/JSON-LD document which you want to convert to XML then provide it as InputStream
to convert method of JsonToXmlConverter.class :
final ByteArrayOutputStream xmlOutput = new ByteArrayOutputStream();
final EventJSONStreamCollector collector = new EventJSONStreamCollector(xmlOutput);
final EventHandler handler = new EventHandler(new EventValidator(), collector);
new JsonToXmlConverter().convert(jsonStream, handler);
System.out.println(out.toString());
The converter functionality is integrated into our tools.openepcis.io. The Docker image used to run it is also publicly available on hub.docker.com at https://hub.docker.com/r/openepcis/tools-ui.
This container includes our complete toolchain, including some parts not available under the open-source license. Most notably, it contains the openepcis-document-converter-sax
, a high-performance streaming implementation of the OpenEPCIS document converter. This SAX-based document converter is part of our business edition and can be integrated via Java SPI. Licensing information can be found here.
OpenEPCIS Tools is a suite of web-based tools designed for handling EPCIS (Electronic Product Code Information Services) documents. It includes functionalities for converting, validating, and visualizing EPCIS data. Users can input EPCIS documents in XML or JSON/JSON-LD formats and obtain transformed documents. The tools are accessible via a user-friendly interface and provide an API for integration with other applications.
By providing either an XML or JSON/JSON-LD EPCIS document as input, users can easily access and obtain the transformed EPCIS document using the web application. You can access the web tool from https://tools.openepcis.io/ui/format-converter.
Users and developers can make use of the API to send requests to the OpenEPCIS document format converter API using an EPCIS document as the input and receive the converted document back as a response. These APIs can also be utilized from within another application’s code or directly online. Users can access the REST endpoint using Swagger-UI from tools.openepcis.io/q/swagger-ui.
-
Pull the Docker image:
docker pull openepcis/tools-ui
-
Run the Docker container:
docker run --rm -t --name openepcis-tools-ui -p 9000:9000 openepcis/tools-ui
-
Pull the Podman image from Docker Hub:
podman pull docker.io/openepcis/tools-ui
-
Run the Podman container:
podman run --rm -t --name openepcis-tools-ui -p 9000:9000 docker.io/openepcis/tools-ui
Service | URL |
---|---|
OpenEPCIS Tools User Interface | http://localhost:9000/openepcis-ui/ |
OpenAPI Swagger-UI | http://localhost:9000/q/swagger-ui/ |
In our OpenEPCIS document converter project, we leverage the Java Service Provider Interface (SPI) to enhance modularity and extendability. SPI is a Java platform feature that allows for service provider modules to be discovered and loaded at runtime. It's like using plug-and-play feature for the code logic, where the system can recognize and work with these accessories automatically. This approach enables our application to be more flexible and scalable by abstracting the core logic of converting documents and allowing for customization without altering the original codebase.
During the JSON/JSON-LD ↔ XML conversion we use the SPI for handling context and namespace resolution, as demonstrated by the ContextHandler
interface. This interface outlines methods for building
JSON-LD contexts (XML -> JSON/JSON-LD conversion using buildJsonContext
method), populating XML namespaces (JSON/JSON-LD -> XML using populateXmlNamespaces
method) conversion, and determining the
applicability of a handler (Default/Custom) for given namespaces or contexts using isContextHandler
method.
We have separate implementations for different standards or custom behaviors. For instance, the DefaultContextHandler
provides generic handling, and we can define our own custom handler by implementing the ContextHandler
interface.
Through SPI, application dynamically discovers and uses these implementations, if no match is found then defaults to DefaultContextHandler
. The project includes the document-converter-extensions
artifact as a dependency. This module contains various implementations and configurations for handling ContextHandler
.
public interface ContextHandler {
void buildJsonContext(final JsonGenerator jsonGenerator, final Map<String, String> namespaces);
void populateXmlNamespaces(final DefaultJsonSchemaNamespaceURIResolver namespaceURIResolver);
boolean isContextHandler(final Map<String, String> namespaces);
}
- Service Provider Configuration File: We must list the fully qualified names of our
ContextHandler
implementations in a service provider configuration file located within theMETA-INF/services
directory. This file is named after the fully qualified interface name, which, in our case, is:
io.openepcis.converter.collector.context.handler.ContextHandler
- ServiceLoader API: At runtime, we employ the
ServiceLoader
API to discover and load availableContextHandler
implementations. This lets our conversion process dynamically adapt to the specifics of the input document, whether it requires default handling or custom logic.
ServiceLoader<ContextHandler> handlers=ServiceLoader.load(ContextHandler.class);
- Dynamic Handler Resolution: During the conversion process, the application iterates over discovered
ContextHandler
instances. It selects the appropriate handler based on the namespaces or contexts of the document being converted, enabling a flexible conversion mechanism that can be easily extended with new handlers for different standards or requirements.
Using SPI in our document converter offers several advantages:
- Extensibility: New context handlers can be easily added without modifying the core conversion logic.
- Decoupling: The conversion logic is decoupled from the specifics of different standards, making the codebase cleaner and more maintainable.
- Adheres to standards: SPI-based approach aligns with modern software design principles, promoting modularity and high cohesion.
If you have any questions or need support, please contact us via email at [email protected]. We welcome contributions from the community. If you would like to contribute:
- Create an Issue: Report bugs or suggest features by creating an issue on our GitHub repository.
- Provide a Fix: Use the standard fork and pull request workflow.
- Fork the repository.
- Make your changes in a new branch.
- Submit a pull request with a detailed description of your changes.
Your input helps us improve and expand the OpenEPCIS Tools, ensuring they meet the needs of all users.