Skip to content

Commit 449ee21

Browse files
feat(gnmi-test-server): add http api to inspect and reset the state
1 parent 585a661 commit 449ee21

File tree

5 files changed

+113
-7
lines changed

5 files changed

+113
-7
lines changed

Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -133,8 +133,8 @@ build-test-gnmi-server: FORCE
133133
@$(CONTAINER_TOOL) build --tag=$(TEST_SERVER_IMG) ./test/gnmi
134134

135135
run-test-gnmi-server: FORCE build-test-gnmi-server
136-
@printf "\e[1;36m>> $(CONTAINER_TOOL) run -p 9339:9339 $(TEST_SERVER_IMG)\e[0m\n"
137-
@$(CONTAINER_TOOL) run --rm -p 9339:9339 $(TEST_SERVER_IMG)
136+
@printf "\e[1;36m>> $(CONTAINER_TOOL) run -p 8000:8000 -p 9339:9339 $(TEST_SERVER_IMG)\e[0m\n"
137+
@$(CONTAINER_TOOL) run --rm -p 8000:8000 -p 9339:9339 $(TEST_SERVER_IMG)
138138

139139
install-goimports: FORCE
140140
@if ! hash goimports 2>/dev/null; then printf "\e[1;36m>> Installing goimports (this may take a while)...\e[0m\n"; go install golang.org/x/tools/cmd/goimports@latest; fi

Makefile.maker.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -172,5 +172,5 @@ verbatim: |
172172
@$(CONTAINER_TOOL) build --tag=$(TEST_SERVER_IMG) ./test/gnmi
173173
174174
run-test-gnmi-server: FORCE build-test-gnmi-server
175-
@printf "\e[1;36m>> $(CONTAINER_TOOL) run -p 9339:9339 $(TEST_SERVER_IMG)\e[0m\n"
176-
@$(CONTAINER_TOOL) run --rm -p 9339:9339 $(TEST_SERVER_IMG)
175+
@printf "\e[1;36m>> $(CONTAINER_TOOL) run -p 8000:8000 -p 9339:9339 $(TEST_SERVER_IMG)\e[0m\n"
176+
@$(CONTAINER_TOOL) run --rm -p 8000:8000 -p 9339:9339 $(TEST_SERVER_IMG)

test/gnmi/Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,4 +33,4 @@ WORKDIR /
3333
COPY --from=build /usr/bin/server /
3434

3535
# Start the server application
36-
CMD ["/server", "--port=9339"]
36+
CMD ["/server", "--port=9339", "--http-port=8000"]

test/gnmi/README.md

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,3 +74,74 @@ Now, it's possible to connect to the server using a GNMI client such as [gnmic](
7474
}
7575
]
7676
```
77+
78+
## HTTP API
79+
80+
In addition to the GNMI gRPC interface, the server also provides an HTTP API for convenient state management and inspection.
81+
82+
### HTTP Server Configuration
83+
84+
The HTTP server runs on port 8000 by default and can be configured using the `--http-port` flag:
85+
86+
```sh
87+
docker run -d -p 9339:9339 -p 8000:8000 ghcr.io/ironcore-dev/gnmi-test-server --http-port 8000
88+
```
89+
90+
### Available Endpoints
91+
92+
#### GET /v1/state
93+
94+
Retrieves the current state of the GNMI server as JSON.
95+
96+
**Example:**
97+
```sh
98+
# Get the current state
99+
curl -s http://127.0.0.1:8000/v1/state
100+
101+
# Response when state is empty:
102+
{}
103+
104+
# Response after setting some values via GNMI:
105+
{
106+
"System": {
107+
"name": "leaf1"
108+
}
109+
}
110+
```
111+
112+
#### DELETE /v1/state
113+
114+
Clears all state from the GNMI server, resetting it to an empty state.
115+
116+
**Example:**
117+
```sh
118+
# Clear all state
119+
curl -X DELETE http://127.0.0.1:8000/v1/state
120+
121+
# Returns HTTP 204 No Content on success
122+
```
123+
124+
### Usage Examples
125+
126+
1. **Inspect state after GNMI operations:**
127+
```sh
128+
# Set a value via GNMI
129+
gnmic -a 127.0.0.1 --port 9339 --insecure set --update-path /System/name --update-value "leaf1"
130+
131+
# Check the state via HTTP
132+
curl http://127.0.0.1:8000/v1/state
133+
```
134+
135+
2. **Reset state for testing:**
136+
```sh
137+
# Clear all state
138+
curl -X DELETE http://127.0.0.1:8000/v1/state
139+
140+
# Verify state is empty
141+
curl http://127.0.0.1:8000/v1/state
142+
```
143+
144+
The HTTP API is particularly useful for:
145+
- Debugging and inspecting the current state
146+
- Automated testing scenarios where you need to reset state between tests
147+
- Integration with monitoring tools that can consume JSON over HTTP

test/gnmi/main.go

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"io"
88
"log"
99
"net"
10+
"net/http"
1011
"strconv"
1112
"strings"
1213
"time"
@@ -256,9 +257,29 @@ func (s *State) Del(path *gpb.Path) {
256257
s.Buf, _ = sjson.DeleteBytes(s.Buf, sb.String()) //nolint:errcheck
257258
}
258259

260+
// handleState handles HTTP requests to the /v1/state endpoint
261+
func (s *Server) handleState(w http.ResponseWriter, r *http.Request) {
262+
switch r.Method {
263+
case http.MethodGet:
264+
w.Header().Set("Content-Type", "application/json")
265+
w.WriteHeader(http.StatusOK)
266+
if len(s.State.Buf) == 0 {
267+
w.Write([]byte("{}"))
268+
return
269+
}
270+
w.Write(s.State.Buf)
271+
case http.MethodDelete:
272+
s.State.Buf = nil
273+
w.WriteHeader(http.StatusNoContent)
274+
default:
275+
w.WriteHeader(http.StatusMethodNotAllowed)
276+
}
277+
}
278+
259279
func main() {
260280
// Parse command line flags
261-
port := flag.Int("port", 9339, "The server port")
281+
port := flag.Int("port", 9339, "The gRPC server port")
282+
httpPort := flag.Int("http-port", 8000, "The HTTP server port")
262283
flag.Parse()
263284

264285
// Create a listener on the specified port
@@ -282,9 +303,23 @@ func main() {
282303
// Enable reflection for easier testing with tools like grpcurl
283304
reflection.Register(grpcServer)
284305

306+
// Setup HTTP server
307+
http.HandleFunc("/v1/state", server.handleState)
308+
httpServer := &http.Server{Addr: fmt.Sprintf(":%d", *httpPort)}
309+
310+
// Start HTTP server in a goroutine
311+
go func() {
312+
log.Printf("Starting HTTP server on port %d", *httpPort)
313+
log.Printf("HTTP endpoint available at: /v1/state")
314+
if err := httpServer.ListenAndServe(); err != nil && err != http.ErrServerClosed {
315+
log.Fatalf("Failed to serve HTTP server: %v", err)
316+
}
317+
}()
318+
285319
log.Printf("Starting gRPC server on port %d", *port)
286320
log.Printf("Server is ready to accept connections...")
287-
log.Printf("Use --port flag to specify a different port (default: 9339)")
321+
log.Printf("Use --port flag to specify a different gRPC port (default: 9339)")
322+
log.Printf("Use --http-port flag to specify a different HTTP port (default: 8000)")
288323
log.Printf("Available services: GNMI")
289324

290325
// Start serving

0 commit comments

Comments
 (0)