or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

attribute-extraction.mdcrud-handlers.mdcrud-operations.mdcustom-resources.mdindex.mdjunit-integration.mdmock-server-management.mdwebsocket-operations.md

crud-handlers.mddocs/

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

```