148 lines
4.6 KiB
C
148 lines
4.6 KiB
C
|
// Copyright 2023 The NATS Authors
|
||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||
|
// you may not use this file except in compliance with the License.
|
||
|
// You may obtain a copy of the License at
|
||
|
//
|
||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||
|
//
|
||
|
// Unless required by applicable law or agreed to in writing, software
|
||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||
|
// See the License for the specific language governing permissions and
|
||
|
// limitations under the License.
|
||
|
|
||
|
#include "examples.h"
|
||
|
|
||
|
// Sequence NATS microservice example.
|
||
|
//
|
||
|
// This example illustrates multiple NATS microservices communicating with each
|
||
|
// other. Please see the main microservice, micro-sequence.c for a more detailed
|
||
|
// explanation.
|
||
|
//
|
||
|
// This specific microservice implements add, multiply, and divide operations.
|
||
|
|
||
|
// arithmeticsOp is a type for a C function that implements am operation: add,
|
||
|
// multiply, divide.
|
||
|
typedef void (*arithmeticsOP)(long double *result, long double a1, long double a2);
|
||
|
|
||
|
// handle_arithmetics_op is a helper function that wraps an implementation of an
|
||
|
// operation into a request handler.
|
||
|
static microError *
|
||
|
handle_arithmetics_op(microRequest *req, arithmeticsOP op)
|
||
|
{
|
||
|
microError *err = NULL;
|
||
|
microArgs *args = NULL;
|
||
|
long double a1, a2, result;
|
||
|
char buf[1024];
|
||
|
int len = 0;
|
||
|
|
||
|
err = micro_ParseArgs(&args, microRequest_GetData(req), microRequest_GetDataLength(req));
|
||
|
if ((err == NULL) && (microArgs_Count(args) != 2))
|
||
|
{
|
||
|
err = micro_Errorf("invalid number of arguments, expected 2 got %d", microArgs_Count(args));
|
||
|
}
|
||
|
if (err == NULL)
|
||
|
err = microArgs_GetFloat(&a1, args, 0);
|
||
|
if (err == NULL)
|
||
|
err = microArgs_GetFloat(&a2, args, 1);
|
||
|
if (err == NULL)
|
||
|
op(&result, a1, a2);
|
||
|
if (err == NULL)
|
||
|
len = snprintf(buf, sizeof(buf), "%Lf", result);
|
||
|
if (err == NULL)
|
||
|
err = microRequest_Respond(req, buf, len);
|
||
|
|
||
|
microArgs_Destroy(args);
|
||
|
return microError_Wrapf(err, "failed to handle arithmetics operation");
|
||
|
}
|
||
|
|
||
|
static void add(long double *result, long double a1, long double a2)
|
||
|
{
|
||
|
*result = a1 + a2;
|
||
|
}
|
||
|
|
||
|
static void divide(long double *result, long double a1, long double a2)
|
||
|
{
|
||
|
*result = a1 / a2;
|
||
|
}
|
||
|
|
||
|
static void multiply(long double *result, long double a1, long double a2)
|
||
|
{
|
||
|
*result = a1 * a2;
|
||
|
}
|
||
|
|
||
|
// request handlers for each operation.
|
||
|
static microError *handle_add(microRequest *req) { return handle_arithmetics_op(req, add); }
|
||
|
static microError *handle_divide(microRequest *req) { return handle_arithmetics_op(req, divide); }
|
||
|
static microError *handle_multiply(microRequest *req) { return handle_arithmetics_op(req, multiply); }
|
||
|
|
||
|
// main is the main entry point for the microservice.
|
||
|
int main(int argc, char **argv)
|
||
|
{
|
||
|
natsStatus s = NATS_OK;
|
||
|
microError *err = NULL;
|
||
|
natsConnection *conn = NULL;
|
||
|
natsOptions *opts = NULL;
|
||
|
microService *m = NULL;
|
||
|
microGroup *g = NULL;
|
||
|
char errorbuf[1024];
|
||
|
|
||
|
microServiceConfig cfg = {
|
||
|
.Description = "Arithmetic operations - NATS microservice example in C",
|
||
|
.Name = "c-arithmetics",
|
||
|
.Version = "1.0.0",
|
||
|
};
|
||
|
microEndpointConfig add_cfg = {
|
||
|
.Name = "add",
|
||
|
.Handler = handle_add,
|
||
|
};
|
||
|
microEndpointConfig divide_cfg = {
|
||
|
.Name = "divide",
|
||
|
.Handler = handle_divide,
|
||
|
};
|
||
|
microEndpointConfig multiply_cfg = {
|
||
|
.Name = "multiply",
|
||
|
.Handler = handle_multiply,
|
||
|
};
|
||
|
|
||
|
// Connect to NATS server
|
||
|
opts = parseArgs(argc, argv, "");
|
||
|
s = natsConnection_Connect(&conn, opts);
|
||
|
if (s != NATS_OK)
|
||
|
{
|
||
|
printf("Error: %u - %s\n", s, natsStatus_GetText(s));
|
||
|
nats_PrintLastErrorStack(stderr);
|
||
|
natsOptions_Destroy(opts);
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
// Create the Microservice that listens on nc.
|
||
|
err = micro_AddService(&m, conn, &cfg);
|
||
|
|
||
|
// Add the endpoints for the functions.
|
||
|
if (err == NULL)
|
||
|
microService_AddGroup(&g, m, "op");
|
||
|
if (err == NULL)
|
||
|
err = microGroup_AddEndpoint(g, &add_cfg);
|
||
|
if (err == NULL)
|
||
|
err = microGroup_AddEndpoint(g, &multiply_cfg);
|
||
|
if (err == NULL)
|
||
|
err = microGroup_AddEndpoint(g, ÷_cfg);
|
||
|
|
||
|
// Run the service, until stopped.
|
||
|
if (err == NULL)
|
||
|
err = microService_Run(m);
|
||
|
|
||
|
// Cleanup.
|
||
|
microService_Destroy(m);
|
||
|
natsOptions_Destroy(opts);
|
||
|
natsConnection_Destroy(conn);
|
||
|
if (err != NULL)
|
||
|
{
|
||
|
printf("Error: %s\n", microError_String(err, errorbuf, sizeof(errorbuf)));
|
||
|
microError_Destroy(err);
|
||
|
return 1;
|
||
|
}
|
||
|
return 0;
|
||
|
}
|