-
Notifications
You must be signed in to change notification settings - Fork 492
/
generate-open-api-spec
executable file
·227 lines (192 loc) · 7.62 KB
/
generate-open-api-spec
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
#!/bin/bash
#
# This script will build an ACA-py docker image,
# execute the openapi/swagger codegen tool and create a swagger.json and openapi.json spec file
# for the ACA-py REST API.
#
##########################################################################################
SWAGGER_GEN_CONTAINER="docker.io/swaggerapi/swagger-codegen-cli:2.4.39"
OPENAPI_GEN_CONTAINER="docker.io/openapitools/openapi-generator-cli:v7.5.0"
# Ensure the script is running from the directory containing this script
cd $(dirname $0)
# Define the root and output directories
ROOT_DIR="${PWD}/.."
OUTPUT_DIR="${ROOT_DIR}/open-api"
##########################################################################################
# Global Defaults and Constants
##########################################################################################
# Set some default values for ACA-Py, including the default image name and ports
ACA_PY_DOCKER_IMAGE_DEFAULT="aries-cloudagent-run"
ACA_PY_ADMIN_PORT="8305"
ACA_PY_INBOUND_PORT="8307"
ACA_PY_DOCKER_PORTS="${ACA_PY_INBOUND_PORT}:${ACA_PY_INBOUND_PORT} ${ACA_PY_ADMIN_PORT}:${ACA_PY_ADMIN_PORT}"
ACA_PY_CMD_OPTIONS=" \
-e http \
--inbound-transport http 0.0.0.0 ${ACA_PY_INBOUND_PORT} \
--outbound-transport http \
--admin 0.0.0.0 ${ACA_PY_ADMIN_PORT} \
--admin-insecure-mode \
--log-level info \
--auto-provision \
--wallet-type askar \
--wallet-name gen-openapi \
--wallet-key gen-openapi-key \
--multitenant \
--multitenant-admin \
--jwt-secret test \
--no-ledger"
# Specify openAPI JSON config file and shared directory
OPEN_API_JSON_CONFIG="openAPIJSON.config"
OPEN_API_SHARED_DIR="${OUTPUT_DIR}/.build"
##########################################################################################
# Functions
##########################################################################################
# Evals a function and exits the script if any error occured
# $1 : String function to evaluate
function runEval() {
cmdOutput=$(eval ${1})
returnValue=$?
if [ $returnValue != 0 ]; then
echo "Command ${1} failed"
exit 1
fi
return $returnValue
}
# Print an indication of script reaching a processing
# milestone in a noticable way
# $1 : Message string to print
function printMilestone() {
echo -e "\n\n##########################################################################################"
echo -e "#"
echo -e "# " ${1}
echo -e "#"
echo -e "##########################################################################################\n"
}
# Wait for a web server to provide a funcitoning interface we can use
# $1 : Url to poll that indicates webserver initialsation complete
# $2 : maximum number of seconds to wait
function waitActiveWebInterface() {
for ((i = 1; i < ${2}; i++)); do
curl -s -f ${1}
if [ $? == 0 ]; then
return 0
fi
echo "Waiting for web interface to activate"
sleep 1
done
echo "**** FAIL - Web interface failed to activate in ${2} seconds. ****"
return 1
}
# Create an ACA-py docker image from the current code checked
# out.
# $1 : The root ACA-py directory to use to create image
# $2 : The tag to use for the created image
function buildACAPyDockerImage() {
local srcDir="${1}"
local tag="${2}"
cd ${srcDir}/scripts
docker build -t ${tag} -f ../docker/Dockerfile.run .. || exit 1
}
# Start an ACA-py docker image
# A simplified version of aries-cloudagent-python/scripts/run_docker
# needed to run without tty or interactive.
# $1: The ACA-py docker image to use (i.e either from a repo or local)
# $2: The port mapping from docker to local host in format "docker1:local1 docker2:local2"
# $3: The ACA-py command line arguments
# $4: The name of a variable to return the continer ID to
function runACAPy() {
local acaPyImage="${1}"
local ports="${2}"
local acaPyArgs="${3}"
local result="${4}"
args=""
for port in ${ports}; do
args="${args} -p ${port}"
done
randName=$(cat /dev/urandom | env LC_ALL=C tr -dc 'a-zA-Z0-9' | fold -w 16 | head -n 1)
acaPyCmd="docker run -d --rm --name ${acaPyImage}_${randName} ${args} \
${acaPyImage} start ${acaPyArgs}"
printMilestone "Starting ACA-py docker image with command: \n \
\t ${acaPyCmd}"
# Return the docker container id for anyone who cares
containerId=$(${acaPyCmd})
local returnStatus=$?
if [[ ${returnStatus} != 0 ]]; then
echo "**** FAIL - ACA-Py failed to start, exiting. ****"
exit 1
fi
if [[ "${result}" ]]; then
eval ${result}="'${containerId}'"
fi
}
OPEN_API_MOUNT="/local"
ACAPY_SPEC_FILE="acapy-raw.json"
CONFIG_LOCATION="${ROOT_DIR}/open-api/${OPEN_API_JSON_CONFIG}"
# Pull the open API docker image and run it against the specified web server
# or local spec file.
# $1 : Web OpenAPI URL or local file to generate API routines from.
# $2 : Language to generate (swagger or openapi)
# $3 : Language config file location
# $4 : The host shared dir for input/output
function runOpenAPIGenerate() {
local specFile="${1}"
local generatorType="${2}"
local configLocation="${3}"
local hostSharedDir="${4}"
runEval "mkdir -p ${hostSharedDir}"
if [ ! -z ${configLocation} ]; then
runEval "cp ${configLocation} ${hostSharedDir}/"
configFile="$(basename -- ${configLocation})"
fi
genSpecCmd="docker run --rm --user 0:0 -v ${hostSharedDir}:${OPEN_API_MOUNT}:z"
# specify language generator.
case ${generatorType} in
swagger)
genSpecCmd+=" ${SWAGGER_GEN_CONTAINER} generate -l swagger"
;;
openapi)
genSpecCmd+=" ${OPENAPI_GEN_CONTAINER} generate -g openapi"
;;
*)
echo "Unknown generator type: ${generatorType}"
exit 1
;;
esac
genSpecCmd+=" --input-spec ${specFile} --output ${OPEN_API_MOUNT}"
if [ ! -z ${configFile} ]; then
genSpecCmd+=" --config ${OPEN_API_MOUNT}/${configFile}"
fi
printMilestone "Starting ${generatorType} code generation with command: \n \
\t ${genSpecCmd}"
${genSpecCmd}
}
##########################################################################################
# Run docker ACA-py image and pull REST API spec file to generate json format
##########################################################################################
# Build the ACA-Py Docker image from the current code
buildACAPyDockerImage "${ROOT_DIR}" "${ACA_PY_DOCKER_IMAGE_DEFAULT}"
# Run the ACA-Py Docker image
runACAPy "${ACA_PY_DOCKER_IMAGE_DEFAULT}" "${ACA_PY_DOCKER_PORTS}" "${ACA_PY_CMD_OPTIONS}" ACA_PY_CONTAINER_ID
# Ensure the ACA-Py container is killed when the script exits
trap 'docker kill ${ACA_PY_CONTAINER_ID}' EXIT
# Wait for the ACA-Py web interface to become active
waitActiveWebInterface "http://localhost:${ACA_PY_ADMIN_PORT}" 20
returnValue=$?
if [ $returnValue != 0 ]; then
exit
fi
printMilestone "ACA-Py Admin interface active\n\t Docker Id '${ACA_PY_CONTAINER_ID}'"
# Create the shared directory if it doesn't already exist
if [ ! -d ${OPEN_API_SHARED_DIR} ]; then
mkdir -p ${OPEN_API_SHARED_DIR}
fi
# Download the Swagger specification from the ACA-Py service
curl --output "${OPEN_API_SHARED_DIR}/${ACAPY_SPEC_FILE}" http://localhost:${ACA_PY_ADMIN_PORT}/api/docs/swagger.json
# Use the OpenAPI Generator to create both Swagger and OpenAPI spec files from the downloaded Swagger specification
runOpenAPIGenerate "${OPEN_API_MOUNT}/${ACAPY_SPEC_FILE}" swagger "${CONFIG_LOCATION}" "${OPEN_API_SHARED_DIR}"
runOpenAPIGenerate "${OPEN_API_MOUNT}/${ACAPY_SPEC_FILE}" openapi "${CONFIG_LOCATION}" "${OPEN_API_SHARED_DIR}"
# Overwrite the existing Swagger and OpenAPI spec files
runEval "cp -f ${OPEN_API_SHARED_DIR}/swagger.json ${ROOT_DIR}/open-api/"
runEval "cp -f ${OPEN_API_SHARED_DIR}/openapi.json ${ROOT_DIR}/open-api/"
# Clean up the working directory.
rm -Rf ${OPEN_API_SHARED_DIR}