https://github.com/release-engineering/kojiji
Koji Java Interface
https://github.com/release-engineering/kojiji
Last synced: about 1 year ago
JSON representation
Koji Java Interface
- Host: GitHub
- URL: https://github.com/release-engineering/kojiji
- Owner: release-engineering
- Created: 2016-01-12T20:35:43.000Z (over 10 years ago)
- Default Branch: master
- Last Pushed: 2025-04-06T05:28:04.000Z (about 1 year ago)
- Last Synced: 2025-04-06T06:25:33.573Z (about 1 year ago)
- Language: Java
- Size: 2.22 MB
- Stars: 6
- Watchers: 7
- Forks: 21
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# Koji Java Interface
This is a Java API for talking to [Koji](https://fedoraproject.org/wiki/Koji).
## Dependencies
* [jHTTPc](https://github.com/commonjava/jhttpc) (Apache httpclient wrapper with SSL certificate-handling improvements, etc.)
* [RWX](https://github.com/commonjava/RWX) (XML-RPC libraries offering flexibility in client choice, annotation-based data binding, etc.)
* [Atlas](https://github.com/commonjava/atlas) (Object model and related utilities for working with Maven artifacts)
## Developing New Kojiji Commands
Currently, the best success I've had in implementing Koji commands within Kojiji uses the following method:
### 1. Capture the Messages Involved
Run the command using the Koji command-line client, with `--debug-xmlrpc` enabled, and save it to a log file:
```
$ koji --debug-xmlrpc list-tags 2>&1 | tee list-tags.log
send: 'POST /kojihub HTTP/1.1\r\nHost: REDACTED\r\nAccept-Encoding: identity\r\nUser-Agent: koji/1.7\r\nContent-Type: text/xml\r\nContent-Length: 107\r\n\r\n'
send: "\n\ngetAPIVersion\n\n\n\n"
reply: 'HTTP/1.1 200 OK\r\n'
header: Date: Thu, 21 Jul 2016 20:36:29 GMT
header: Server: Apache/2.2.15 (Red Hat)
header: Strict-Transport-Security: max-age=63072000; includeSubDomains
header: Content-Length: 121
header: Connection: close
header: Content-Type: text/xml
body: "\n\n\n\n1\n\n\n\n"
send: 'POST /kojihub HTTP/1.1\r\nHost: REDACTED\r\nAccept-Encoding: identity\r\nUser-Agent: koji/1.7\r\nContent-Type: text/xml\r\nContent-Length: 178\r\n\r\n'
send: "\n\nlistTags\n\n\n\n\n\n\n\n"
reply: 'HTTP/1.1 200 OK\r\n'
header: Date: Thu, 21 Jul 2016 20:36:30 GMT
header: Server: Apache/2.2.15 (Red Hat)
header: Strict-Transport-Security: max-age=63072000; includeSubDomains
header: Content-Length: 5693545
header: Connection: close
header: Content-Type: text/xml
body: "\n\n
[...]
```
### 2. Split the Messages into Exchanges
Use the `koji-output-tidy.py` helper script in `research/` to generate a series of message-exchange files in a new folder:
```
$ mkdir research/list-tags
$ ./research/koji-output-tidy.py list-tags.log research/list-tags/list-tags
Opening temp/list-tags-1.txt
Closing temp/list-tags-1.txt (10 lines)
Opening temp/list-tags-2.txt
Closing temp/list-tags-2.txt (717 lines)
```
### 3. Redact Sensitive Information in Research Folder
Your captured HTTP exchanges will contain server addresses and XML-RPC endpoint information. **Please take great care to redact this information, in order to avoid any sort of security problem with running systems.**
### 4. Implement the Model Classes
For each file in the output directory, implement the appropriate object-model classes in the `com.redhat.red.build.koji.model.xmlrpc.messages` package, using the RWX bindings, to model the XML request and response. Here's part of an example message exchange file containing some of the `list-tags` result from above:
```
listTags
HTTP/1.1 200 OK
Date: Thu, 21 Jul 2016 20:36:30 GMT
Server: Apache/2.2.15 (Red Hat)
Strict-Transport-Security: max-age=63072000; includeSubDomains
Content-Length: 5693545
Connection: close
Content-Type: text/xml
maven_support
0
locked
0
name
my-tag
perm
id
1
arches
i386
maven_include_all
0
[...]
```
For this example, the corresponding object-model classes are [com.redhat.red.build.koji.model.xmlrpc.messages.ListTagsRequest](https://github.com/release-engineering/kojiji/blob/master/src/main/java/com/redhat/red/build/koji/model/xmlrpc/messages/ListTagsRequest.java) and [com.redhat.red.build.koji.model.xmlrpc.messages.ListTagsResponse](https://github.com/release-engineering/kojiji/blob/master/src/main/java/com/redhat/red/build/koji/model/xmlrpc/messages/ListTagsResponse.java).
### 5. Factor Out Common Payload Sections
Many requests / responses will contain the same types of information. These should be factored out into common object-model classes that can be reused between message class types. These live in the `com.redhat.red.build.koji.model.xmlrpc` package. For instance, multiple Koji calls may return build information as part of the response. This information is captured by the class [com.redhat.red.build.koji.model.xmlrpc.KojiBuildInfo](https://github.com/release-engineering/kojiji/blob/master/src/main/java/com/redhat/red/build/koji/model/xmlrpc/KojiBuildInfo.java).
### 6. Write Unit Tests
You already have sample XML for the request and response messages that Koji expects. From here, you can turn them into unit tests that verify round-trip serialization / deserialization to XML for your new model classes. By chopping up each message exchange into its constituent XML documents and saving them in `src/test/resources`, you can implement something like the following minimal set of unit tests:
* [com.redhat.red.build.koji.model.xmlrpc.messages.ListTagsRequestTest](https://github.com/release-engineering/kojiji/blob/master/src/test/java/com/redhat/red/build/koji/model/xmlrpc/messages/ListTagsRequestTest.java)
* [com.redhat.red.build.koji.model.xmlrpc.messages.ListTagsResponseTest](https://github.com/release-engineering/kojiji/blob/master/src/test/java/com/redhat/red/build/koji/model/xmlrpc/messages/ListTagsResponseTest.java)
### 7. TO BE DOCUMENTED: Integration Testing
Unit tests are fine for verifying compatibility with a message protocol from a given point in time, but what happens if that message protocol changes? The only way to be really certain of compatibility with a particular version of Koji is to run tests that talk to a live instance. We have some of these tests already, which use a suite of Docker containers at build time to provision a Koji environment for testing purposes. After the build completes, these instances are torn down and discarded (after logs and other files pertinent to the test results have been retrieved, of course). To support this, we're using a project called [koji-dojo](https://github.com/release-engineering/koji-dojo).
While this is a great way to be absolutely certain of compatibility, it is definitely labor intensive. It takes quite a bit of work to define the initial state of the system and then load it just in time for a test to use it. And beyond test data management, it becomes important to be able to simulate certain actions within the Koji environment (like builds taking place) in order to ensure the database is in a valid state. This is where we need to go next, and some of Kojiji's commands don't have integration tests now because we have yet to mock the logic that Koji's builder daemon uses to register a completed build.