0
# CRUD Handlers
1
2
Low-level HTTP request handlers that implement Kubernetes-compatible CRUD operations. These handlers process individual HTTP requests and manage resource lifecycle operations in CRUD mode.
3
4
## Capabilities
5
6
### KubernetesCrudDispatcherHandler Interface
7
8
Core functional interface that defines the contract for handling HTTP requests in CRUD mode.
9
10
```java { .api }
11
@FunctionalInterface
12
public interface KubernetesCrudDispatcherHandler {
13
14
// HTTP status codes
15
int HTTP_UNPROCESSABLE_ENTITY = 422;
16
String KIND = "kind";
17
String STATUS = "status";
18
19
/**
20
* Handle an HTTP request and return appropriate response
21
* @param request - Recorded HTTP request with path, headers, and body
22
* @return MockResponse with status code and response body
23
* @throws KubernetesCrudDispatcherException - For validation or processing errors
24
*/
25
default MockResponse handle(RecordedRequest request) throws KubernetesCrudDispatcherException;
26
27
/**
28
* Handle an HTTP request with decomposed parameters
29
* @param path - Request path
30
* @param contentType - Content-Type header value
31
* @param requestBody - Request body content
32
* @return MockResponse with appropriate status and body
33
* @throws KubernetesCrudDispatcherException - For validation or processing errors
34
*/
35
MockResponse handle(String path, String contentType, String requestBody)
36
throws KubernetesCrudDispatcherException;
37
38
/**
39
* Validate that resource metadata matches the request path
40
* @param query - Parsed path attributes
41
* @param updatedResource - Resource JSON node
42
* @throws KubernetesCrudDispatcherException - If name or namespace mismatch
43
*/
44
default void validatePath(AttributeSet query, JsonNode updatedResource)
45
throws KubernetesCrudDispatcherException;
46
47
/**
48
* Validate resource version for optimistic concurrency control
49
* @param currentResource - Current resource state
50
* @param updatedResource - Updated resource with version
51
* @throws KubernetesCrudDispatcherException - For version conflicts
52
*/
53
default void validateResourceVersion(JsonNode currentResource, JsonNode updatedResource)
54
throws KubernetesCrudDispatcherException;
55
56
/**
57
* Validate and parse request body into a Kubernetes resource
58
* @param requestBody - JSON request body
59
* @return Parsed GenericKubernetesResource
60
* @throws KubernetesCrudDispatcherException - For invalid JSON or missing required fields
61
*/
62
default GenericKubernetesResource validateRequestBody(String requestBody)
63
throws KubernetesCrudDispatcherException;
64
65
/**
66
* Check if the request path targets a status subresource
67
* @param path - HTTP request path
68
* @return true if path ends with "/status"
69
*/
70
static boolean isStatusPath(String path);
71
72
/**
73
* Set or remove status field from a resource JSON node
74
* @param source - Resource JSON node to modify
75
* @param status - Status JSON node to set, or null to remove
76
*/
77
static void setStatus(JsonNode source, JsonNode status);
78
}
79
```
80
81
### PostHandler
82
83
Handles HTTP POST requests for resource creation, including metadata initialization and name generation.
84
85
```java { .api }
86
public class PostHandler implements KubernetesCrudDispatcherHandler {
87
88
/**
89
* Create a new PostHandler with required dependencies
90
* @param attributeExtractor - For parsing paths and resources
91
* @param persistence - For storing and retrieving resources
92
*/
93
public PostHandler(KubernetesAttributesExtractor attributeExtractor,
94
KubernetesCrudPersistence persistence);
95
96
/**
97
* Handle resource creation request
98
* @param path - Creation path (e.g., "/api/v1/namespaces/default/pods")
99
* @param contentType - Request content type
100
* @param requestBody - Resource JSON to create
101
* @return MockResponse with created resource and 201 status
102
* @throws KubernetesCrudDispatcherException - For validation errors
103
*/
104
@Override
105
public MockResponse handle(String path, String contentType, String requestBody)
106
throws KubernetesCrudDispatcherException;
107
}
108
```
109
110
### PutHandler
111
112
Handles HTTP PUT requests for resource updates and replacements.
113
114
```java { .api }
115
public class PutHandler implements KubernetesCrudDispatcherHandler {
116
117
/**
118
* Create a new PutHandler with required dependencies
119
* @param attributeExtractor - For parsing paths and resources
120
* @param persistence - For storing and retrieving resources
121
*/
122
public PutHandler(KubernetesAttributesExtractor attributeExtractor,
123
KubernetesCrudPersistence persistence);
124
125
/**
126
* Handle resource update/replacement request
127
* @param path - Update path (e.g., "/api/v1/namespaces/default/pods/my-pod")
128
* @param contentType - Request content type
129
* @param requestBody - Updated resource JSON
130
* @return MockResponse with updated resource and 200 status
131
* @throws KubernetesCrudDispatcherException - For validation or conflict errors
132
*/
133
@Override
134
public MockResponse handle(String path, String contentType, String requestBody)
135
throws KubernetesCrudDispatcherException;
136
}
137
```
138
139
### PatchHandler
140
141
Handles HTTP PATCH requests supporting both JSON Patch (RFC 6902) and JSON Merge Patch (RFC 7396).
142
143
```java { .api }
144
public class PatchHandler implements KubernetesCrudDispatcherHandler {
145
146
/**
147
* Create a new PatchHandler with required dependencies
148
* @param attributeExtractor - For parsing paths and resources
149
* @param persistence - For storing and retrieving resources
150
*/
151
public PatchHandler(KubernetesAttributesExtractor attributeExtractor,
152
KubernetesCrudPersistence persistence);
153
154
/**
155
* Handle resource patch request with support for multiple patch formats
156
* @param path - Patch path (e.g., "/api/v1/namespaces/default/pods/my-pod")
157
* @param contentType - Patch content type (application/json-patch+json or application/merge-patch+json)
158
* @param requestBody - Patch operations or merge patch JSON
159
* @return MockResponse with patched resource and 200 status
160
* @throws KubernetesCrudDispatcherException - For validation or patch application errors
161
*/
162
@Override
163
public MockResponse handle(String path, String contentType, String requestBody)
164
throws KubernetesCrudDispatcherException;
165
}
166
```
167
168
## Handler Operation Details
169
170
### Resource Creation (POST)
171
172
The PostHandler manages resource creation with these features:
173
174
- **Metadata Initialization**: Automatically sets `metadata.uid`, `metadata.creationTimestamp`, and `metadata.resourceVersion`
175
- **Name Generation**: Supports `generateName` for automatic unique name creation
176
- **Namespace Defaulting**: Sets default namespace if not specified for namespaced resources
177
- **Conflict Detection**: Prevents duplicate resource creation
178
179
### Resource Updates (PUT)
180
181
The PutHandler handles complete resource replacement:
182
183
- **Optimistic Concurrency**: Validates `resourceVersion` to prevent conflicting updates
184
- **Status Subresource**: Supports separate status updates via `/status` path
185
- **Finalizer Processing**: Handles finalizer-based deletion patterns
186
- **Metadata Preservation**: Maintains immutable metadata fields
187
188
### Resource Patching (PATCH)
189
190
The PatchHandler supports multiple patch formats:
191
192
- **JSON Patch (RFC 6902)**: Array of operations (add, remove, replace, move, copy, test)
193
- **JSON Merge Patch (RFC 7396)**: Partial resource updates with merge semantics
194
- **Content Type Detection**: Automatically selects patch strategy based on Content-Type header
195
- **Deep Merging**: Handles nested object updates correctly
196
197
## Error Handling
198
199
All handlers use `KubernetesCrudDispatcherException` for consistent error reporting:
200
201
```java
202
try {
203
// Handler operation
204
} catch (KubernetesCrudDispatcherException e) {
205
// Returns appropriate HTTP status and Kubernetes Status object
206
return new MockResponse()
207
.setResponseCode(e.getCode())
208
.setBody(e.toStatusBody());
209
}
210
```
211
212
## Usage Examples
213
214
### Create Resource
215
216
```java
217
PostHandler handler = new PostHandler(attributeExtractor, persistence);
218
219
String podJson = """
220
{
221
"apiVersion": "v1",
222
"kind": "Pod",
223
"metadata": {
224
"name": "test-pod",
225
"namespace": "default"
226
},
227
"spec": {
228
"containers": [{"name": "app", "image": "nginx"}]
229
}
230
}
231
""";
232
233
MockResponse response = handler.handle(
234
"/api/v1/namespaces/default/pods",
235
"application/json",
236
podJson);
237
// Returns 201 Created with initialized metadata
238
```
239
240
### Update Resource
241
242
```java
243
PutHandler handler = new PutHandler(attributeExtractor, persistence);
244
245
MockResponse response = handler.handle(
246
"/api/v1/namespaces/default/pods/test-pod",
247
"application/json",
248
updatedPodJson);
249
// Returns 200 OK with updated resource
250
```
251
252
### Patch Resource
253
254
```java
255
PatchHandler handler = new PatchHandler(attributeExtractor, persistence);
256
257
// JSON Merge Patch
258
String mergePatch = """
259
{
260
"metadata": {
261
"labels": {
262
"version": "2.0"
263
}
264
}
265
}
266
""";
267
268
MockResponse response = handler.handle(
269
"/api/v1/namespaces/default/pods/test-pod",
270
"application/merge-patch+json",
271
mergePatch);
272
// Returns 200 OK with patched resource
273
```