1 /*
2 * Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7 #include "restapi_service_context.h"
8
9 #include <stdlib.h>
10 #include <string.h>
11
12 #include "rpc/http/caller/http_caller.h"
13 #include "trace.h"
14
15 /**
16 * A service_context that represents a service instance reached via
17 * a remote REST API
18 */
19 struct restapi_service_context {
20 struct service_context service_context;
21 char rpc_call_url[HTTP_CALLER_MAX_URL_LEN];
22 };
23
24 /* Concrete service_context methods */
25 static rpc_session_handle restapi_service_context_open(void *context, struct rpc_caller **caller);
26 static void restapi_service_context_close(void *context, rpc_session_handle session_handle);
27 static void restapi_service_context_relinquish(void *context);
28
restapi_service_context_create(const char * service_url)29 struct service_context *restapi_service_context_create(const char *service_url)
30 {
31 struct restapi_service_context *new_context =
32 (struct restapi_service_context *)calloc(1, sizeof(struct restapi_service_context));
33
34 if (!new_context) {
35 EMSG("Failed to alloc restapi_service_context");
36 return NULL;
37 }
38
39 strncpy(new_context->rpc_call_url, service_url, HTTP_CALLER_MAX_URL_LEN - 1);
40 strncat(new_context->rpc_call_url, "call/", HTTP_CALLER_MAX_URL_LEN - 1);
41
42 new_context->service_context.context = new_context;
43 new_context->service_context.open = restapi_service_context_open;
44 new_context->service_context.close = restapi_service_context_close;
45 new_context->service_context.relinquish = restapi_service_context_relinquish;
46
47 return &new_context->service_context;
48 }
49
restapi_service_context_open(void * context,struct rpc_caller ** caller)50 static rpc_session_handle restapi_service_context_open(void *context, struct rpc_caller **caller)
51 {
52 struct restapi_service_context *this_context = (struct restapi_service_context *)context;
53 rpc_session_handle session_handle = NULL;
54
55 struct http_caller *http_caller =
56 (struct http_caller *)calloc(1, sizeof(struct http_caller));
57
58 if (http_caller) {
59 *caller = http_caller_init(http_caller);
60
61 int status = http_caller_open(http_caller, this_context->rpc_call_url);
62
63 if (status == 0) {
64 /* Successfully opened session */
65 session_handle = http_caller;
66 } else {
67 /* Failed to open session */
68 http_caller_close(http_caller);
69 http_caller_deinit(http_caller);
70 free(http_caller);
71 }
72 }
73
74 return session_handle;
75 }
76
restapi_service_context_close(void * context,rpc_session_handle session_handle)77 static void restapi_service_context_close(void *context, rpc_session_handle session_handle)
78 {
79 struct http_caller *http_caller = (struct http_caller *)session_handle;
80
81 (void)context;
82
83 if (http_caller) {
84 http_caller_close(http_caller);
85 http_caller_deinit(http_caller);
86 free(http_caller);
87 }
88 }
89
restapi_service_context_relinquish(void * context)90 static void restapi_service_context_relinquish(void *context)
91 {
92 struct restapi_service_context *this_context = (struct restapi_service_context *)context;
93
94 free(this_context);
95 }
96