xref: /aosp_15_r20/external/sdk-platform-java/gapic-generator-java/DEVELOPMENT.md (revision 882aa7c72c3cd3b66e72a261bdd69b93f7de7670)
1*882aa7c7SMatt Gilbride# Development Workflow
2*882aa7c7SMatt Gilbride
3*882aa7c7SMatt Gilbride## Test Running
4*882aa7c7SMatt Gilbride
5*882aa7c7SMatt Gilbride### Unit Tests
6*882aa7c7SMatt Gilbride
7*882aa7c7SMatt GilbrideTo run the unit tests in `gapic-generator-java` submodule, first build all
8*882aa7c7SMatt Gilbridemodules with `mvn -pl '!gapic-generator-java' install -DskipTests` at the root
9*882aa7c7SMatt Gilbridedirectory,
10*882aa7c7SMatt Gilbridethen `cd` into `gapic-generator-java` submodule for the following commands:
11*882aa7c7SMatt Gilbride
12*882aa7c7SMatt Gilbride- Run all unit tests:
13*882aa7c7SMatt Gilbride
14*882aa7c7SMatt Gilbride  ```sh
15*882aa7c7SMatt Gilbride  # In gapic-generator-java submodule
16*882aa7c7SMatt Gilbride  mvn test
17*882aa7c7SMatt Gilbride  ```
18*882aa7c7SMatt Gilbride
19*882aa7c7SMatt Gilbride- Run a single or multiple unit tests:
20*882aa7c7SMatt Gilbride
21*882aa7c7SMatt Gilbride  ```sh
22*882aa7c7SMatt Gilbride  # In gapic-generator-java submodule
23*882aa7c7SMatt Gilbride  mvn test -Dtest=JavaCodeGeneratorTest
24*882aa7c7SMatt Gilbride
25*882aa7c7SMatt Gilbride  mvn test "-Dtest=Basic*, !%regex[.*.Unstable.*], !%regex[.*.MyTest.class#one.*|two.*], %regex[#fast.*|slow.*]"
26*882aa7c7SMatt Gilbride  ```
27*882aa7c7SMatt Gilbride
28*882aa7c7SMatt Gilbride- Update all unit test golden files:
29*882aa7c7SMatt Gilbride
30*882aa7c7SMatt Gilbride  ```sh
31*882aa7c7SMatt Gilbride  # In gapic-generator-java submodule
32*882aa7c7SMatt Gilbride  mvn test -DupdateUnitGoldens
33*882aa7c7SMatt Gilbride  ```
34*882aa7c7SMatt Gilbride
35*882aa7c7SMatt Gilbride- Update a single unit test golden file, for example `JavaCodeGeneratorTest.java`:
36*882aa7c7SMatt Gilbride
37*882aa7c7SMatt Gilbride  ```sh
38*882aa7c7SMatt Gilbride  # In gapic-generator-java submodule
39*882aa7c7SMatt Gilbride  mvn test -DupdateUnitGoldens -Dtest=JavaCodeGeneratorTest
40*882aa7c7SMatt Gilbride  ```
41*882aa7c7SMatt Gilbride
42*882aa7c7SMatt GilbrideNote that `mvn -pl '!gapic-generator-java' install -DskipTests`
43*882aa7c7SMatt Gilbrideat the root directory is needed for `mvn test` commands,
44*882aa7c7SMatt Gilbridebecause the gapic-generator-java submodule depends on the "test jars" of
45*882aa7c7SMatt Gilbridegax-java. The test jars are absent until Maven's "package" phase, which is later
46*882aa7c7SMatt Gilbridethan the "test" phase.
47*882aa7c7SMatt Gilbride
48*882aa7c7SMatt Gilbride### Integration Tests
49*882aa7c7SMatt Gilbride
50*882aa7c7SMatt GilbrideTo run integration test for gapic-generator-java, run this Bazel command in the
51*882aa7c7SMatt Gilbrideroot of the repository (where you have WORKSPACE file for Bazel.)
52*882aa7c7SMatt Gilbride
53*882aa7c7SMatt Gilbride```sh
54*882aa7c7SMatt Gilbride# In the repository root directory
55*882aa7c7SMatt Gilbridebazelisk test //...  # integration tests
56*882aa7c7SMatt Gilbride```
57*882aa7c7SMatt Gilbride
58*882aa7c7SMatt Gilbride
59*882aa7c7SMatt Gilbride- Run a single integration test for API like `Redis`, it generates Java source
60*882aa7c7SMatt Gilbride  code using the Java microgenerator and compares them with the goldens files
61*882aa7c7SMatt Gilbride  in `test/integration/goldens/redis`.
62*882aa7c7SMatt Gilbride
63*882aa7c7SMatt Gilbride    ```sh
64*882aa7c7SMatt Gilbride    # In the repository root directory
65*882aa7c7SMatt Gilbride    bazelisk test //test/integration:redis
66*882aa7c7SMatt Gilbride    ```
67*882aa7c7SMatt Gilbride
68*882aa7c7SMatt Gilbride- Update integration test golden files, for example `Redis`. This clobbers all the
69*882aa7c7SMatt Gilbride  files in `test/integration/goldens/redis`.
70*882aa7c7SMatt Gilbride
71*882aa7c7SMatt Gilbride    ```sh
72*882aa7c7SMatt Gilbride    # In the repository root directory
73*882aa7c7SMatt Gilbride    bazelisk run //test/integration:update_redis
74*882aa7c7SMatt Gilbride    ```
75*882aa7c7SMatt Gilbride
76*882aa7c7SMatt Gilbride## Running the Plugin under googleapis with local gapic-generator-java
77*882aa7c7SMatt Gilbride
78*882aa7c7SMatt GilbrideFor running the Plugin with showcase protos and local gapic-generator-java, see
79*882aa7c7SMatt Gilbride[Showcase Integration Testing](../showcase/README.md).
80*882aa7c7SMatt Gilbride
81*882aa7c7SMatt GilbrideTo generate a production GAPIC API:
82*882aa7c7SMatt Gilbride
83*882aa7c7SMatt Gilbride1. Clone [googleapis](https://github.com/googleapis/googleapis).
84*882aa7c7SMatt Gilbride
85*882aa7c7SMatt Gilbride2. Modify `googleapis/WORKSPACE` to point to local gapic-generator-java
86*882aa7c7SMatt Gilbride
87*882aa7c7SMatt Gilbride   Normally, googleapis's build pulls in gapic-generator-java from Maven Central.
88*882aa7c7SMatt Gilbride   For a local run, we first need to build a local SNAPSHOT jar of the generator. Then we point googleapis to
89*882aa7c7SMatt Gilbride   both the local SNAPSHOT jar and the local copy of the generator.
90*882aa7c7SMatt Gilbride
91*882aa7c7SMatt Gilbride   Replace the following section in googleapis
92*882aa7c7SMatt Gilbride   ```
93*882aa7c7SMatt Gilbride    _gapic_generator_java_version = "2.13.0"
94*882aa7c7SMatt Gilbride
95*882aa7c7SMatt Gilbride    maven_install(
96*882aa7c7SMatt Gilbride        artifacts = [
97*882aa7c7SMatt Gilbride            "com.google.api:gapic-generator-java:" + _gapic_generator_java_version,
98*882aa7c7SMatt Gilbride        ],
99*882aa7c7SMatt Gilbride        #Update this False for local development
100*882aa7c7SMatt Gilbride        fail_on_missing_checksum = True,
101*882aa7c7SMatt Gilbride        repositories = [
102*882aa7c7SMatt Gilbride            "m2Local",
103*882aa7c7SMatt Gilbride            "https://repo.maven.apache.org/maven2/",
104*882aa7c7SMatt Gilbride        ]
105*882aa7c7SMatt Gilbride    )
106*882aa7c7SMatt Gilbride
107*882aa7c7SMatt Gilbride    http_archive(
108*882aa7c7SMatt Gilbride        name = "gapic_generator_java",
109*882aa7c7SMatt Gilbride        strip_prefix = "gapic-generator-java-%s" % _gapic_generator_java_version,
110*882aa7c7SMatt Gilbride        urls = ["https://github.com/googleapis/gapic-generator-java/archive/v%s.zip" % _gapic_generator_java_version],
111*882aa7c7SMatt Gilbride    )
112*882aa7c7SMatt Gilbride
113*882aa7c7SMatt Gilbride    # gax-java is part of gapic-generator-java repository
114*882aa7c7SMatt Gilbride    http_archive(
115*882aa7c7SMatt Gilbride        name = "com_google_api_gax_java",
116*882aa7c7SMatt Gilbride        strip_prefix = "gapic-generator-java-%s/gax-java" % _gapic_generator_java_version,
117*882aa7c7SMatt Gilbride        urls = ["https://github.com/googleapis/gapic-generator-java/archive/v%s.zip" % _gapic_generator_java_version],
118*882aa7c7SMatt Gilbride    )
119*882aa7c7SMatt Gilbride   ```
120*882aa7c7SMatt Gilbride
121*882aa7c7SMatt Gilbride   to
122*882aa7c7SMatt Gilbride   ```
123*882aa7c7SMatt Gilbride    _gapic_generator_java_version = "2.15.4-SNAPSHOT"
124*882aa7c7SMatt Gilbride
125*882aa7c7SMatt Gilbride    maven_install(
126*882aa7c7SMatt Gilbride        artifacts = [
127*882aa7c7SMatt Gilbride            "com.google.api:gapic-generator-java:" + _gapic_generator_java_version,
128*882aa7c7SMatt Gilbride        ],
129*882aa7c7SMatt Gilbride        #Update this False for local development
130*882aa7c7SMatt Gilbride        fail_on_missing_checksum = False,
131*882aa7c7SMatt Gilbride        repositories = [
132*882aa7c7SMatt Gilbride            "m2Local",
133*882aa7c7SMatt Gilbride            "https://repo.maven.apache.org/maven2/",
134*882aa7c7SMatt Gilbride        ]
135*882aa7c7SMatt Gilbride    )
136*882aa7c7SMatt Gilbride
137*882aa7c7SMatt Gilbride    local_repository(
138*882aa7c7SMatt Gilbride        name = "gapic_generator_java",
139*882aa7c7SMatt Gilbride        path = "/absolute/path/to/your/local/gapic-generator-java",
140*882aa7c7SMatt Gilbride    )
141*882aa7c7SMatt Gilbride
142*882aa7c7SMatt Gilbride    # gax-java is part of gapic-generator-java repository
143*882aa7c7SMatt Gilbride    local_repository(
144*882aa7c7SMatt Gilbride        name = "com_google_api_gax_java",
145*882aa7c7SMatt Gilbride        path = "/absolute/path/to/your/local/gapic-generator-java/gax-java",
146*882aa7c7SMatt Gilbride    )
147*882aa7c7SMatt Gilbride   ```
148*882aa7c7SMatt Gilbride
149*882aa7c7SMatt Gilbride   Note: At the time of writing, the gapic-generator version was `2.13.0`. Update the version to the latest version in the pom.xml
150*882aa7c7SMatt Gilbride
151*882aa7c7SMatt Gilbride3. Build the new target.
152*882aa7c7SMatt Gilbride
153*882aa7c7SMatt Gilbride   You can generate any client library based on the protos within googleapis.
154*882aa7c7SMatt Gilbride   You just need the name of the service within the `java_gapic_assembly_gradle_pkg`
155*882aa7c7SMatt Gilbride   rules within the service's `BUILD.bazel` file.
156*882aa7c7SMatt Gilbride   For instance, to run your local generator on the `speech`'s v2 service, you can
157*882aa7c7SMatt Gilbride   run:
158*882aa7c7SMatt Gilbride
159*882aa7c7SMatt Gilbride   ```
160*882aa7c7SMatt Gilbride   bazelisk build //google/cloud/speech/v2:google-cloud-speech-v2-java
161*882aa7c7SMatt Gilbride   ```
162*882aa7c7SMatt Gilbride
163*882aa7c7SMatt Gilbride   Note: If you are running into bazel build issues, you can try to remove gapic-generator-java cached in your local m2
164*882aa7c7SMatt Gilbride   Try running this command:
165*882aa7c7SMatt Gilbride   ```
166*882aa7c7SMatt Gilbride    rm -rf ~/.m2/repository/com/google/api/
167*882aa7c7SMatt Gilbride   ```
168*882aa7c7SMatt Gilbride   and then rebuild gapic-generator-java (`mvn clean install`).
169*882aa7c7SMatt Gilbride
170*882aa7c7SMatt Gilbride## Debugging the gapic-generator-java running on protobuf compiler
171*882aa7c7SMatt Gilbride
172*882aa7c7SMatt Gilbride1. In [googleapis](https://github.com/googleapis/googleapis) root directory, run the following commands:
173*882aa7c7SMatt Gilbride   1. Set `JVM_DEBUG_PORT` environment variable.
174*882aa7c7SMatt Gilbride       ```shell
175*882aa7c7SMatt Gilbride       export JVM_DEBUG_PORT=5005
176*882aa7c7SMatt Gilbride       ```
177*882aa7c7SMatt Gilbride      The protobuf compiler runs the `protoc-gen-java_gapic` shell script (a wrapper of java command with an option to specify JVM debugging).
178*882aa7c7SMatt Gilbride      We set the environment variable `JVM_DEBUG_PORT` to enable the debug option.
179*882aa7c7SMatt Gilbride
180*882aa7c7SMatt Gilbride   2. Run the command to build a client library, e.g., `java-monitoring`, with `--subcommands` flag to output commands spawned by `bazel build`.
181*882aa7c7SMatt Gilbride      ```shell
182*882aa7c7SMatt Gilbride      bazel build --subcommands //google/monitoring/v3:google-cloud-monitoring-v3-java
183*882aa7c7SMatt Gilbride      ```
184*882aa7c7SMatt Gilbride   3. In the output, find the command of protobuf compiler invocation with gapic-generator-java plugin (the `darwin_arm64-opt-exec-2B5CBBC6` part may be different on your environment).
185*882aa7c7SMatt Gilbride
186*882aa7c7SMatt Gilbride      Note that different client libraries have different proto files.
187*882aa7c7SMatt Gilbride      ```shell
188*882aa7c7SMatt Gilbride      bazel-out/darwin_arm64-opt-exec-2B5CBBC6/bin/external/com_google_protobuf/protoc --experimental_allow_proto3_optional '--plugin=protoc-gen-java_gapic=bazel-out/darwin_arm64-opt-exec-2B5CBBC6/bin/external/gapic_generator_java/protoc-gen-java_gapic' '--java_gapic_out=metadata:bazel-out/darwin_arm64-fastbuild/bin/google/monitoring/v3/monitoring_java_gapic_srcjar_raw.srcjar.zip' '--java_gapic_opt=transport=grpc,rest-numeric-enums,grpc-service-config=google/monitoring/v3/monitoring_grpc_service_config.json,gapic-config=google/monitoring/v3/monitoring_gapic.yaml,api-service-config=google/monitoring/v3/monitoring.yaml' '-Igoogle/monitoring/v3/alert.proto=google/monitoring/v3/alert.proto' '-Igoogle/monitoring/v3/alert_service.proto=google/monitoring/v3/alert_service.proto' '-Igoogle/monitoring/v3/common.proto=google/monitoring/v3/common.proto' '-Igoogle/monitoring/v3/dropped_labels.proto=google/monitoring/v3/dropped_labels.proto' '-Igoogle/monitoring/v3/group.proto=google/monitoring/v3/group.proto' '-Igoogle/monitoring/v3/group_service.proto=google/monitoring/v3/group_service.proto' '-Igoogle/monitoring/v3/metric.proto=google/monitoring/v3/metric.proto' '-Igoogle/monitoring/v3/metric_service.proto=google/monitoring/v3/metric_service.proto' '-Igoogle/monitoring/v3/mutation_record.proto=google/monitoring/v3/mutation_record.proto' '-Igoogle/monitoring/v3/notification.proto=google/monitoring/v3/notification.proto' '-Igoogle/monitoring/v3/notification_service.proto=google/monitoring/v3/notification_service.proto' '-Igoogle/monitoring/v3/query_service.proto=google/monitoring/v3/query_service.proto' '-Igoogle/monitoring/v3/service.proto=google/monitoring/v3/service.proto' '-Igoogle/monitoring/v3/service_service.proto=google/monitoring/v3/service_service.proto' '-Igoogle/monitoring/v3/snooze.proto=google/monitoring/v3/snooze.proto' '-Igoogle/monitoring/v3/snooze_service.proto=google/monitoring/v3/snooze_service.proto' '-Igoogle/monitoring/v3/span_context.proto=google/monitoring/v3/span_context.proto' '-Igoogle/monitoring/v3/uptime.proto=google/monitoring/v3/uptime.proto' '-Igoogle/monitoring/v3/uptime_service.proto=google/monitoring/v3/uptime_service.proto' '-Igoogle/api/annotations.proto=google/api/annotations.proto' '-Igoogle/api/http.proto=google/api/http.proto' '-Igoogle/protobuf/descriptor.proto=bazel-out/darwin_arm64-fastbuild/bin/external/com_google_protobuf/_virtual_imports/descriptor_proto/google/protobuf/descriptor.proto' '-Igoogle/api/client.proto=google/api/client.proto' '-Igoogle/api/launch_stage.proto=google/api/launch_stage.proto' '-Igoogle/protobuf/duration.proto=bazel-out/darwin_arm64-fastbuild/bin/external/com_google_protobuf/_virtual_imports/duration_proto/google/protobuf/duration.proto' '-Igoogle/api/distribution.proto=google/api/distribution.proto' '-Igoogle/protobuf/any.proto=bazel-out/darwin_arm64-fastbuild/bin/external/com_google_protobuf/_virtual_imports/any_proto/google/protobuf/any.proto' '-Igoogle/protobuf/timestamp.proto=bazel-out/darwin_arm64-fastbuild/bin/external/com_google_protobuf/_virtual_imports/timestamp_proto/google/protobuf/timestamp.proto' '-Igoogle/api/field_behavior.proto=google/api/field_behavior.proto' '-Igoogle/api/label.proto=google/api/label.proto' '-Igoogle/api/metric.proto=google/api/metric.proto' '-Igoogle/api/monitored_resource.proto=google/api/monitored_resource.proto' '-Igoogle/protobuf/struct.proto=bazel-out/darwin_arm64-fastbuild/bin/external/com_google_protobuf/_virtual_imports/struct_proto/google/protobuf/struct.proto' '-Igoogle/api/resource.proto=google/api/resource.proto' '-Igoogle/rpc/status.proto=google/rpc/status.proto' '-Igoogle/type/calendar_period.proto=google/type/calendar_period.proto' '-Igoogle/protobuf/empty.proto=bazel-out/darwin_arm64-fastbuild/bin/external/com_google_protobuf/_virtual_imports/empty_proto/google/protobuf/empty.proto' '-Igoogle/protobuf/field_mask.proto=bazel-out/darwin_arm64-fastbuild/bin/external/com_google_protobuf/_virtual_imports/field_mask_proto/google/protobuf/field_mask.proto' '-Igoogle/protobuf/wrappers.proto=bazel-out/darwin_arm64-fastbuild/bin/external/com_google_protobuf/_virtual_imports/wrappers_proto/google/protobuf/wrappers.proto' '-Igoogle/cloud/common_resources.proto=google/cloud/common_resources.proto' google/monitoring/v3/alert.proto google/monitoring/v3/alert_service.proto google/monitoring/v3/common.proto google/monitoring/v3/dropped_labels.proto google/monitoring/v3/group.proto google/monitoring/v3/group_service.proto google/monitoring/v3/metric.proto google/monitoring/v3/metric_service.proto google/monitoring/v3/mutation_record.proto google/monitoring/v3/notification.proto google/monitoring/v3/notification_service.proto google/monitoring/v3/query_service.proto google/monitoring/v3/service.proto google/monitoring/v3/service_service.proto google/monitoring/v3/snooze.proto google/monitoring/v3/snooze_service.proto google/monitoring/v3/span_context.proto google/monitoring/v3/uptime.proto google/monitoring/v3/uptime_service.proto google/cloud/common_resources.proto
189*882aa7c7SMatt Gilbride      ```
190*882aa7c7SMatt Gilbride   4. Run the protoc command.
191*882aa7c7SMatt Gilbride
192*882aa7c7SMatt Gilbride      It shows nothing because it's waiting for a debugger to attach.
193*882aa7c7SMatt Gilbride
194*882aa7c7SMatt Gilbride2. In the IntelliJ that has gapic-generator-java, add [Remote JVM debug configuration](https://www.jetbrains.com/help/idea/tutorial-remote-debug.html).
195*882aa7c7SMatt Gilbride
196*882aa7c7SMatt Gilbride3. Set a breakpoint, e.g., in the 1st line in the main method in [Main](src/main/java/com/google/api/generator/Main.java) (this line always get called).
197*882aa7c7SMatt Gilbride
198*882aa7c7SMatt Gilbride4. Start the Remote JVM Debug configuration and you can debug the generator in Intellij.
199*882aa7c7SMatt Gilbride   ![IntelliJ Debug Screenshot](debug.png)
200*882aa7c7SMatt Gilbride
201*882aa7c7SMatt Gilbride## FAQ
202*882aa7c7SMatt Gilbride
203*882aa7c7SMatt Gilbride### Error in workspace: workspace() got unexpected keyword argument 'managed_directories'
204*882aa7c7SMatt Gilbride
205*882aa7c7SMatt GilbrideFull Error:
206*882aa7c7SMatt Gilbride
207*882aa7c7SMatt Gilbride```
208*882aa7c7SMatt GilbrideERROR: Traceback (most recent call last):
209*882aa7c7SMatt Gilbride        File "/home/alicejli/googleapis/WORKSPACE", line 1, column 10, in <toplevel>
210*882aa7c7SMatt Gilbride                workspace(
211*882aa7c7SMatt GilbrideError in workspace: workspace() got unexpected keyword argument 'managed_directories'
212*882aa7c7SMatt GilbrideERROR: Error computing the main repository mapping: Encountered error while reading extension file 'tools/build_defs/repo/http.bzl': no such package '@bazel_tools//tools/build_defs/repo': error loading package 'external': Could not load //external package
213*882aa7c7SMatt Gilbride```
214*882aa7c7SMatt Gilbride
215*882aa7c7SMatt GilbrideYou may be using the latest version of bazel which this project does not support yet. Try installing bazelisk to force
216*882aa7c7SMatt Gilbridebazel to use the version specified in `.bazeliskrc`
217*882aa7c7SMatt Gilbride
218