blob: 6283ec8991634bdc26c5290a52be652c9c008f30 [file] [log] [blame]
Ray Milkey3275ae82018-05-29 15:35:36 -07001"""
2 Copyright 2018-present Open Networking Foundation
3
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15"""
16
Ray Milkey7dac7da2017-08-01 16:56:05 -070017load("//tools/build/bazel:generate_workspace.bzl", "COMPILE", "TEST")
18load("//tools/build/bazel:variables.bzl", "ONOS_VERSION")
19load("//tools/build/bazel:generate_test_rules.bzl", "generate_test_rules")
Ray Milkeyb7949e72018-06-19 18:31:02 -070020load("//tools/build/bazel:checkstyle.bzl", "checkstyle_test")
Ray Milkey7dac7da2017-08-01 16:56:05 -070021
Ray Milkey32ea35c2018-06-06 15:28:07 -070022def _all_java_sources():
Ray Milkey0bcdfd12018-05-23 14:07:19 -070023 return native.glob(["src/main/java/**/*.java"])
Ray Milkey7dac7da2017-08-01 16:56:05 -070024
Ray Milkey32ea35c2018-06-06 15:28:07 -070025def _all_java_test_sources():
Ray Milkey0bcdfd12018-05-23 14:07:19 -070026 return native.glob(["src/test/java/**/*.java"])
Ray Milkey7dac7da2017-08-01 16:56:05 -070027
Ray Milkey32ea35c2018-06-06 15:28:07 -070028def _all_test_resources():
Ray Milkey0bcdfd12018-05-23 14:07:19 -070029 return native.glob(["src/test/resources/**"])
Ray Milkey7dac7da2017-08-01 16:56:05 -070030
Ray Milkey32ea35c2018-06-06 15:28:07 -070031def _all_resources(resources_root):
Ray Milkey0bcdfd12018-05-23 14:07:19 -070032 if resources_root == None:
33 return native.glob(["src/main/resources/**"])
34 else:
35 return native.glob([resources_root + "**"])
Ray Milkey7dac7da2017-08-01 16:56:05 -070036
Ray Milkey25747d82018-06-13 14:12:51 -070037def _webapp():
38 return native.glob(["src/main/webapp/**"])
39
Ray Milkey275af2c2018-06-15 13:05:08 -070040"""
41 Implementation of the rule to call bnd to make an OSGI jar file
42"""
Ray Milkey7dac7da2017-08-01 16:56:05 -070043def _bnd_impl(ctx):
Ray Milkey3275ae82018-05-29 15:35:36 -070044 if (len(ctx.files.source) == 1):
45 input_file = ctx.files.source[0]
46 else:
47 # this is a list of inputs. The one we want is the last one
48 # in the list that isn't a source jar
49 for file in reversed(ctx.files.source):
50 if ("-src" in file.path):
51 continue
52 else:
53 input_file = file
54 break
55
56 jar = input_file.path
Ray Milkey0bcdfd12018-05-23 14:07:19 -070057 output = ctx.outputs.osgi_jar.path
Thomas Vachuska8e022a92018-07-10 14:47:38 -070058 name = ctx.attr.name
Ray Milkey275af2c2018-06-15 13:05:08 -070059 group = ctx.attr.group
Ray Milkey0bcdfd12018-05-23 14:07:19 -070060 version = ctx.attr.version
61 license = ""
Ray Milkey12ae6ca2018-06-11 15:34:30 -070062 import_packages = ctx.attr.import_packages
Ray Milkey0bcdfd12018-05-23 14:07:19 -070063 exportPackages = "*"
64 includeResources = ""
Ray Milkey25747d82018-06-13 14:12:51 -070065 web_context = ctx.attr.web_context
66 if web_context == None or web_context == "":
67 web_context = "NONE"
68 web_xml = ctx.attr.web_xml
Ray Milkey0bcdfd12018-05-23 14:07:19 -070069 dynamicimportPackages = ""
Ray Milkey3275ae82018-05-29 15:35:36 -070070 cp = ""
Ray Milkey7dac7da2017-08-01 16:56:05 -070071
Ray Milkey3275ae82018-05-29 15:35:36 -070072 inputDependencies = [input_file]
Ray Milkey7dac7da2017-08-01 16:56:05 -070073
Ray Milkey0bcdfd12018-05-23 14:07:19 -070074 # determine the dependencies and build the class path
75 for dep in ctx.attr.deps:
Ray Milkey25b785a2018-06-12 09:59:14 -070076 if java_common.provider in dep:
77 file = dep.files.to_list()[0]
Ray Milkey472d8392018-05-23 17:06:51 -070078
Ray Milkey25b785a2018-06-12 09:59:14 -070079 if cp:
80 cp += ":"
81 cp += file.path
82 inputDependencies = inputDependencies + [file]
Ray Milkey7dac7da2017-08-01 16:56:05 -070083
Ray Milkey0bcdfd12018-05-23 14:07:19 -070084 # extract the class files for use by bnd
Ray Milkey3275ae82018-05-29 15:35:36 -070085 classes = ctx.actions.declare_file("classes" + ctx.label.name.replace("/", "-"))
Ray Milkey0bcdfd12018-05-23 14:07:19 -070086 classesPath = classes.path
87 jarCommand = "mkdir -p %s && cp %s %s && cd %s && jar xf *.jar" % (classesPath, jar, classesPath, classesPath)
88 ctx.actions.run_shell(
89 inputs = inputDependencies,
90 outputs = [classes],
91 command = jarCommand,
92 progress_message = "Expanding jar file: %s" % jar,
93 )
94 inputDependencies += [classes]
Ray Milkey25747d82018-06-13 14:12:51 -070095 web_xml_root_path = ""
96 if len(web_xml) != 0:
97 web_xml_root = web_xml[0].files.to_list()[0]
98 inputDependencies += [web_xml_root]
99 web_xml_root_path = web_xml_root.path.replace("WEB-INF/web.xml", "")
Ray Milkey7dac7da2017-08-01 16:56:05 -0700100
Ray Milkey0bcdfd12018-05-23 14:07:19 -0700101 # call bnd to make the OSGI jar file
102 arguments = [
103 jar,
104 output,
105 cp,
106 name,
107 group,
108 version,
109 license,
Ray Milkey12ae6ca2018-06-11 15:34:30 -0700110 import_packages,
Ray Milkey0bcdfd12018-05-23 14:07:19 -0700111 exportPackages,
112 includeResources,
Ray Milkey25747d82018-06-13 14:12:51 -0700113 web_context,
114 web_xml_root_path,
Ray Milkey0bcdfd12018-05-23 14:07:19 -0700115 dynamicimportPackages,
116 classesPath,
117 ]
Ray Milkey12ae6ca2018-06-11 15:34:30 -0700118
Ray Milkey0bcdfd12018-05-23 14:07:19 -0700119 ctx.actions.run(
120 inputs = inputDependencies,
121 outputs = [ctx.outputs.osgi_jar],
122 arguments = arguments,
123 progress_message = "Running bnd wrapper on: %s" % ctx.attr.name,
124 executable = ctx.executable._bnd_exe,
125 )
Ray Milkey7dac7da2017-08-01 16:56:05 -0700126
Ray Milkey25b785a2018-06-12 09:59:14 -0700127 deps = []
128 if java_common.provider in ctx.attr.source:
129 deps.append(ctx.attr.source[java_common.provider])
130 deps_provider = java_common.merge(deps)
131 return struct(
Ray Milkey15053f02018-06-13 10:00:45 -0700132 providers = [deps_provider],
Ray Milkey25b785a2018-06-12 09:59:14 -0700133 )
134
Ray Milkey275af2c2018-06-15 13:05:08 -0700135"""
136 Rule definition for calling bnd to make an OSGi jar file.
137"""
Ray Milkey32ea35c2018-06-06 15:28:07 -0700138_bnd = rule(
Ray Milkey7dac7da2017-08-01 16:56:05 -0700139 attrs = {
140 "deps": attr.label_list(),
141 "version": attr.string(),
Ray Milkey275af2c2018-06-15 13:05:08 -0700142 "group": attr.string(),
Ray Milkey3275ae82018-05-29 15:35:36 -0700143 "source": attr.label(),
Ray Milkey12ae6ca2018-06-11 15:34:30 -0700144 "import_packages": attr.string(),
Ray Milkey25747d82018-06-13 14:12:51 -0700145 "web_context": attr.string(),
146 "web_xml": attr.label_list(allow_files = True),
Ray Milkey7dac7da2017-08-01 16:56:05 -0700147 "_bnd_exe": attr.label(
148 executable = True,
149 cfg = "host",
150 allow_files = True,
151 default = Label("//utils/osgiwrap:osgi-jar"),
152 ),
153 },
154 fragments = ["java"],
155 outputs = {
156 "osgi_jar": "lib%{name}.jar",
157 },
158 implementation = _bnd_impl,
159)
160
Ray Milkey275af2c2018-06-15 13:05:08 -0700161"""
162 Implementation of the rule to call swagger generator to create the registrator java class source
163"""
164def _swagger_java_impl(ctx):
165 api_title = ctx.attr.api_title
166 api_version = ctx.attr.api_version
167 api_description = ctx.attr.api_description
168 api_package = ctx.attr.api_package
169 web_context = ctx.attr.web_context
170
171 output_java = ctx.outputs.swagger_java.path
172 output_dir = output_java [:output_java.find("generated-sources")]
173
174 package_name = ctx.attr.package_name
175
176 srcs_arg = ""
177 resources_arg = ""
178 input_dependencies = []
179
180 for file in ctx.files.srcs:
181 srcs_arg += file.path + ","
182 input_dependencies.append(file)
183
184 for resource in resources_arg:
185 resources_arg += resource.path + ","
186
187 # call swagger generator to make the swagger JSON and java files
188 arguments = [
189 srcs_arg,
190 resources_arg,
191 "",
192 package_name + "/src/main/resources",
193 output_dir,
194 output_dir,
195 web_context,
196 api_title,
197 api_version,
198 api_package,
199 api_description,
200 ]
201
202 ctx.actions.run(
203 inputs = ctx.files.srcs,
204 outputs = [ctx.outputs.swagger_java],
205 arguments = arguments,
206 progress_message = "Running swagger generator on: %s" % ctx.attr.name,
207 executable = ctx.executable._swagger_generator_exe,
208 )
209
210"""
211Implementation of the rule to call swagger generator for swagger.json file
212"""
213def _swagger_json_impl(ctx):
214 api_title = ctx.attr.api_title
215 api_version = ctx.attr.api_version
216 api_description = ctx.attr.api_description
217 api_package = ctx.attr.api_package
218 web_context = ctx.attr.web_context
219
220 output_json = ctx.outputs.swagger_json.path
221 output_dir = output_json[:output_json.find("swagger.json")]
222
223 package_name = ctx.attr.package_name
224
225 srcs_arg = ""
226 resources_arg = ""
227 input_dependencies = []
228
229 for file in ctx.files.srcs:
230 srcs_arg += file.path + ","
231 input_dependencies.append(file)
232
233 for resource in resources_arg:
234 resources_arg += resource.path + ","
235
236 # call swagger generator to make the swagger JSON and java files
237 arguments = [
238 srcs_arg,
239 resources_arg,
240 "",
241 package_name + "/src/main/resources",
242 output_dir,
243 output_dir,
244 web_context,
245 api_title,
246 api_version,
247 api_package,
248 api_description,
249 ]
250
251 ctx.actions.run(
252 inputs = ctx.files.srcs,
253 outputs = [ctx.outputs.swagger_json],
254 arguments = arguments,
255 progress_message = "Running swagger generator on: %s" % ctx.attr.name,
256 executable = ctx.executable._swagger_generator_exe,
257 )
258
259"""
260 Rule definition to call swagger generator to create the registrator java class source
261"""
262_swagger_java = rule(
263 attrs = {
264 "srcs": attr.label_list(allow_files = True),
265 "package_name": attr.string(),
266 "api_title": attr.string(),
267 "api_version": attr.string(),
268 "api_description": attr.string(),
269 "api_package": attr.string(),
270 "web_context": attr.string(),
271 "_swagger_generator_exe": attr.label(
272 executable = True,
273 cfg = "host",
274 allow_files = True,
275 default = Label("//tools/build/buck-plugin:swagger_generator"),
276 ),
277 "swagger_java": attr.output(),
278 },
279 fragments = ["java"],
280 implementation = _swagger_java_impl,
281)
282
283"""
284 Rule definition to call swagger generator to create the swagger JSON
285"""
286_swagger_json = rule(
287 attrs = {
288 "srcs": attr.label_list(allow_files = True),
289 "package_name": attr.string(),
290 "api_title": attr.string(),
291 "api_version": attr.string(),
292 "api_description": attr.string(),
293 "api_package": attr.string(),
294 "web_context": attr.string(),
295 "_swagger_generator_exe": attr.label(
296 executable = True,
297 cfg = "host",
298 allow_files = True,
299 default = Label("//tools/build/buck-plugin:swagger_generator"),
300 ),
301 "swagger_json": attr.output(),
302 },
303 fragments = ["java"],
304 implementation = _swagger_json_impl,
305)
306
307"""
308 Converts a jar file to an OSGI compatible jar file.
309
310 Args:
311 name: name of the rule to create the OSGI jar file - required
312 jar: jar file to convert - required target
313 deps: dependencies needed by the jar file - required list of targets
314 version: Version of the generated jar file. Optional, defaults to the current ONOS version
315 group: Maven group ID for the resulting jar file. Optional, defaults to 'org.onosproject'
316 import_packages: OSGI import list. Optional, comma separated list, defaults to "*"
317 visibility: Visibility of the produced jar file to other BUILDs. Optional, defaults to private
318"""
Ray Milkey25747d82018-06-13 14:12:51 -0700319def wrapped_osgi_jar(
320 name,
321 jar,
322 deps,
323 version = ONOS_VERSION,
Ray Milkey275af2c2018-06-15 13:05:08 -0700324 group = "org.onosproject",
Ray Milkey25747d82018-06-13 14:12:51 -0700325 import_packages = "*",
Ray Milkey25747d82018-06-13 14:12:51 -0700326 visibility = ["//visibility:private"]):
327 _bnd(
328 name = name,
329 source = jar,
330 deps = deps,
331 version = version,
Ray Milkey275af2c2018-06-15 13:05:08 -0700332 group = group,
Ray Milkey25747d82018-06-13 14:12:51 -0700333 visibility = visibility,
334 import_packages = import_packages,
Ray Milkey275af2c2018-06-15 13:05:08 -0700335 web_xml = None,
Ray Milkey25747d82018-06-13 14:12:51 -0700336 )
Ray Milkey7dac7da2017-08-01 16:56:05 -0700337
Ray Milkey275af2c2018-06-15 13:05:08 -0700338"""
339 Creates an OSGI jar and test jar file from a set of source and test files.
340 See osgi_jar() for a description of shared parameters.
341 Args:
342 test_srcs: Test source file(s) to compile. Optional list of targets, defaults to src/test/java/**/*.java
343 test_deps: Dependencies for the test jar. Optional list of targets, defaults to a common set of dependencies
344 test_resources: Resources to include in the test jar. Optional list of targets, defaults to src/test/resources/**
345 exclude_tests: Tests that should not be run. Useful for excluding things like test files without any @Test methods.
346 Optional ist of targets, defaults to []
347"""
Ray Milkey0bcdfd12018-05-23 14:07:19 -0700348def osgi_jar_with_tests(
349 name = None,
350 deps = None,
351 test_deps = None,
Ray Milkey275af2c2018-06-15 13:05:08 -0700352 group = "org.onosproject",
Ray Milkey0bcdfd12018-05-23 14:07:19 -0700353 srcs = None,
354 resources_root = None,
355 resources = None,
356 test_srcs = None,
357 exclude_tests = None,
358 test_resources = None,
359 visibility = ["//visibility:public"],
Ray Milkey12ae6ca2018-06-11 15:34:30 -0700360 version = ONOS_VERSION,
Ray Milkey25747d82018-06-13 14:12:51 -0700361 web_context = None,
362 api_title = "",
363 api_version = "",
364 api_description = "",
365 api_package = "",
Ray Milkey15053f02018-06-13 10:00:45 -0700366 import_packages = None):
Ray Milkey0bcdfd12018-05-23 14:07:19 -0700367 if name == None:
368 name = "onos-" + native.package_name().replace("/", "-")
Ray Milkey7dac7da2017-08-01 16:56:05 -0700369 if srcs == None:
Ray Milkey32ea35c2018-06-06 15:28:07 -0700370 srcs = _all_java_sources()
Ray Milkey0bcdfd12018-05-23 14:07:19 -0700371 if resources == None:
Ray Milkey32ea35c2018-06-06 15:28:07 -0700372 resources = _all_resources(resources_root)
Ray Milkey0bcdfd12018-05-23 14:07:19 -0700373 if test_srcs == None:
Ray Milkey32ea35c2018-06-06 15:28:07 -0700374 test_srcs = _all_java_test_sources()
Ray Milkey0bcdfd12018-05-23 14:07:19 -0700375 if test_resources == None:
Ray Milkey32ea35c2018-06-06 15:28:07 -0700376 test_resources = _all_test_resources()
Ray Milkey0bcdfd12018-05-23 14:07:19 -0700377 if exclude_tests == None:
378 exclude_tests = []
Ray Milkey7dac7da2017-08-01 16:56:05 -0700379 if deps == None:
Ray Milkey0bcdfd12018-05-23 14:07:19 -0700380 deps = COMPILE
381 if test_deps == None:
382 test_deps = TEST
Ray Milkey12ae6ca2018-06-11 15:34:30 -0700383 if import_packages == None:
384 import_packages = "*"
Ray Milkey0bcdfd12018-05-23 14:07:19 -0700385 tests_name = name + "-tests"
386 tests_jar_deps = list(depset(deps + test_deps)) + [name]
387 all_test_deps = tests_jar_deps + [tests_name]
Ray Milkey25747d82018-06-13 14:12:51 -0700388 web_xml = _webapp()
Ray Milkey7dac7da2017-08-01 16:56:05 -0700389
Ray Milkey275af2c2018-06-15 13:05:08 -0700390 native_srcs = srcs
391 native_resources = resources
392 if web_context != None and api_title != None and len(resources) != 0:
393 # generate Swagger files if needed
394 _swagger_java(
395 name = name + "_swagger_java",
396 srcs = srcs + resources,
397 package_name = native.package_name(),
398 api_title = api_title,
399 api_version = api_version,
400 api_description = api_description,
401 web_context = web_context,
402 api_package = api_package,
403 swagger_java = ("src/main/resources/apidoc/generated-sources/" +
404 api_package.replace(".", "/") +
405 "/ApiDocRegistrator.java").replace("//", "/"),
406 )
407 _swagger_json(
408 name = name + "_swagger_json",
409 srcs = srcs + resources,
410 package_name = native.package_name(),
411 api_title = api_title,
412 api_version = api_version,
413 api_description = api_description,
414 web_context = web_context,
415 api_package = api_package,
416 swagger_json = "src/main/resources/apidoc/swagger.json",
417 )
418 native_resources = []
419 for r in resources:
420 if not "definitions" in r:
421 native_resources.append(r)
422 native_srcs = srcs + [ name + "_swagger_java" ]
423 native_resources.append(name + "_swagger_json");
424
Ray Milkey25747d82018-06-13 14:12:51 -0700425 # compile the Java code
Ray Milkey275af2c2018-06-15 13:05:08 -0700426 native.java_library(name = name + "-native", srcs = native_srcs, resources = native_resources, deps = deps, visibility = visibility)
Ray Milkey25747d82018-06-13 14:12:51 -0700427
Ray Milkey32ea35c2018-06-06 15:28:07 -0700428 _bnd(
Ray Milkey25b785a2018-06-12 09:59:14 -0700429 name = name,
430 source = name + "-native",
Ray Milkey32ea35c2018-06-06 15:28:07 -0700431 deps = deps,
432 version = version,
Ray Milkey275af2c2018-06-15 13:05:08 -0700433 group = group,
Ray Milkey32ea35c2018-06-06 15:28:07 -0700434 visibility = visibility,
Ray Milkey12ae6ca2018-06-11 15:34:30 -0700435 import_packages = import_packages,
Ray Milkey25747d82018-06-13 14:12:51 -0700436 web_context = web_context,
437 web_xml = web_xml,
Ray Milkey32ea35c2018-06-06 15:28:07 -0700438 )
Ray Milkey0bcdfd12018-05-23 14:07:19 -0700439 if test_srcs != []:
440 native.java_library(
441 name = tests_name,
442 srcs = test_srcs,
443 resources = test_resources,
444 deps = tests_jar_deps,
445 visibility = visibility,
446 )
Ray Milkey7dac7da2017-08-01 16:56:05 -0700447
Ray Milkey0bcdfd12018-05-23 14:07:19 -0700448 generate_test_rules(
449 name = name + "-tests-gen",
450 test_files = test_srcs,
451 exclude_tests = exclude_tests,
452 deps = all_test_deps,
453 )
454
Ray Milkeyb7949e72018-06-19 18:31:02 -0700455 checkstyle_test(
456 name = name + "_checkstyle_test",
457 srcs = srcs,
458 )
459
Ray Milkey275af2c2018-06-15 13:05:08 -0700460"""
461 Creates an OSGI jar file from a set of source files.
462
463 Args:
464 name: Name of the rule to generate. Optional, defaults to a name based on the location in the source tree.
465 For example apps/mcast/app becomes onos-apps-mcast-app
466 deps: Dependencies of the generated jar file. Expressed as a list of targets
467 import_packages: OSGI import list. Optional, comma separated list, defaults to "*"
468 group: Maven group ID for the resulting jar file. Optional, defaults to 'org.onosproject'
469 srcs: Source file(s) to compile. Optional list of targets, defaults to src/main/java/**/*.java
470 resources_root: Relative path to the root of the tree of resources for this jar. Optional, defaults to src/main/resources
471 resources: Resources to include in the jar file. Optional list of targets, defaults to all files beneath resources_root
472 visibility: Visibility of the produced jar file to other BUILDs. Optional, defaults to public
473 version: Version of the generated jar file. Optional, defaults to the current ONOS version
474 web_context: Web context for a WAB file if needed. Only needed if the jar file provides a REST API. Optional string
475 api_title: Swagger API title. Optional string, only used if the jar file provides a REST API and has swagger annotations
476 api_version: Swagger API version. Optional string, only used if the jar file provides a REST API and has swagger annotations
477 api_description: Swagger API description. Optional string, only used if the jar file provides a REST API and has swagger annotations
478 api_package: Swagger API package name. Optional string, only used if the jar file provides a REST API and has swagger annotations
479"""
Ray Milkey0bcdfd12018-05-23 14:07:19 -0700480def osgi_jar(
481 name = None,
482 deps = None,
Ray Milkey12ae6ca2018-06-11 15:34:30 -0700483 import_packages = None,
Ray Milkey275af2c2018-06-15 13:05:08 -0700484 group = "org.onosproject",
Ray Milkey0bcdfd12018-05-23 14:07:19 -0700485 srcs = None,
486 resources_root = None,
487 resources = None,
488 visibility = ["//visibility:public"],
Ray Milkey12ae6ca2018-06-11 15:34:30 -0700489 version = ONOS_VERSION,
Ray Milkey25747d82018-06-13 14:12:51 -0700490 web_context = None,
Ray Milkey12ae6ca2018-06-11 15:34:30 -0700491 api_title = "",
492 api_version = "",
493 api_description = "",
Ray Milkey15053f02018-06-13 10:00:45 -0700494 api_package = ""):
Ray Milkey0bcdfd12018-05-23 14:07:19 -0700495 if srcs == None:
Ray Milkey32ea35c2018-06-06 15:28:07 -0700496 srcs = _all_java_sources()
Ray Milkey0bcdfd12018-05-23 14:07:19 -0700497 if deps == None:
498 deps = COMPILE
499
500 osgi_jar_with_tests(
501 name = name,
502 deps = deps,
503 test_deps = [],
Ray Milkey275af2c2018-06-15 13:05:08 -0700504 group = group,
Ray Milkey0bcdfd12018-05-23 14:07:19 -0700505 srcs = srcs,
506 resources = resources,
507 resources_root = resources_root,
508 test_srcs = [],
509 exclude_tests = [],
510 test_resources = [],
511 visibility = visibility,
512 version = version,
Ray Milkey12ae6ca2018-06-11 15:34:30 -0700513 import_packages = import_packages,
Ray Milkey275af2c2018-06-15 13:05:08 -0700514 api_title = api_title,
515 api_version = api_version,
516 api_description = api_description,
517 api_package = api_package,
Ray Milkey25747d82018-06-13 14:12:51 -0700518 web_context = web_context,
Ray Milkey0bcdfd12018-05-23 14:07:19 -0700519 )