What is YANG?

YANG is a data modeling language widely used in networking for modeling configuration and operational data of network devices. It is used alongside protocols like NETCONF, RESTCONF, and gRPC.

lighty.io provides a unified API for YANG-modeled data transformations — essential for integrating with external systems and for serializing/deserializing data across protocol boundaries.

Step 1: Define the RPC in YANG

rpc compute-sum {
    input {
        leaf operand-a {
            type uint16;
            mandatory true;
        }
        leaf operand-b {
            type uint16;
            mandatory true;
        }
    }
    output {
        leaf sum {
            type uint32;
            mandatory true;
        }
    }
}

Step 2: Generate Java Classes

Use the ODL yang-maven-plugin in your pom.xml to auto-generate Java interfaces and classes from the YANG model. This produces a LightyRpcExampleService interface with a computeSum() method.

Step 3: Implement the Service

public class LightyRpcExampleServiceImpl implements LightyRpcExampleService {
    public Future<RpcResult<ComputeSumOutput>> computeSum(ComputeSumInput input) {
        return RpcResultBuilder.success(
                new ComputeSumOutputBuilder()
                        .setSum((long) input.getOperandA() + input.getOperandB())
                        .build())
                .buildFuture();
    }
}

Step 4: Initialize Schema Context

Load all available YANG models from the classpath and create a schema context:

List<YangModuleInfo> moduleInfos = new LinkedList<>();
ServiceLoader<YangModelBindingProvider> yangProviderLoader =
    ServiceLoader.load(YangModelBindingProvider.class);
for (YangModelBindingProvider provider : yangProviderLoader) {
    moduleInfos.add(provider.getModuleInfo());
}

ModuleInfoBackedContext moduleInfoBackedCntxt = ModuleInfoBackedContext.create();
moduleInfoBackedCntxt.addModuleInfos(moduleInfos);
SchemaContext schemaContext = moduleInfoBackedCntxt
    .tryToCreateSchemaContext().get();

Step 5: Handle HTTP Requests with Codecs

// Deserialize incoming JSON payload
DataCodec<ComputeSumInput> dataCodec = new DataCodec<>(schemaContext);
NormalizedNode rpcInputNode =
    dataCodec.withJson().deserialize(rpcDef, new StringReader(payload));
ComputeSumInput rpcInput =
    dataCodec.convertToBindingAwareRpc(rpcDef.getInput().getPath(),
                                        (ContainerNode) rpcInputNode);

// Call the RPC implementation
ComputeSumOutput rpcOutput = rpcImpl.computeSum(rpcInput).get().getResult();

// Serialize output back to JSON
Writer output = dataCodec.withJson().serializeRpc(
    rpcDef.getOutput(),
    dataCodec.convertToBindingIndependentRpc(rpcOutput)
);

Test It

curl -H "Content-Type: application/json" \
     -X POST \
     -d '{ "input": { "operand-a": 200, "operand-b": 22 }}' \
     http://localhost:8080

Expected response:

{"output":{"sum":222}}

Sample Application Output

Loading Yang model schema context
Yang model schema context loaded
Loaded definition of RPC: compute-sum
HTTP server started at port 8080
Press any key to exit...
Received payload: { "input": { "operand-a": 200, "operand-b": 22 }}
RPC output: {"output":{"sum":222}}
Key concept: lighty.io's Codecs component provides a unified API for YANG-modeled data transformations. It bridges the gap between YANG-modeled data and Java objects, making it straightforward to expose any ODL service over any transport protocol.