Add plugin overview page
Change-Id: Ia6181e68df82ce8cf16f19550aa17016f0dc7af0
diff --git a/.gitignore b/.gitignore
index 0f23a78..2913dab 100644
--- a/.gitignore
+++ b/.gitignore
@@ -9,3 +9,4 @@
/termmapper
*.yaml
\#*
+/cmd/termmapper
\ No newline at end of file
diff --git a/cmd/termmapper/fuzz_test.go b/cmd/termmapper/fuzz_test.go
index 6ff68d2..ee5c80d 100644
--- a/cmd/termmapper/fuzz_test.go
+++ b/cmd/termmapper/fuzz_test.go
@@ -49,18 +49,29 @@
f.Fatal(err)
}
+ // Create mock config for testing
+ mockConfig := &tmconfig.MappingLists{
+ Lists: []tmconfig.MappingList{mappingList},
+ }
+
// Create fiber app
app := fiber.New(fiber.Config{
DisableStartupMessage: true,
ErrorHandler: func(c *fiber.Ctx, err error) error {
- // Ensure we always return a valid JSON response even for panic cases
+ // For body limit errors, return 413 status code
+ if err.Error() == "body size exceeds the given limit" || errors.Is(err, fiber.ErrRequestEntityTooLarge) {
+ return c.Status(fiber.StatusRequestEntityTooLarge).JSON(fiber.Map{
+ "error": fmt.Sprintf("request body too large (max %d bytes)", maxInputLength),
+ })
+ }
+ // For other errors, return 500 status code
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
- "error": "internal server error",
+ "error": err.Error(),
})
},
BodyLimit: maxInputLength,
})
- setupRoutes(app, m)
+ setupRoutes(app, m, mockConfig)
// Add seed corpus
f.Add("test-mapper", "atob", "", "", "", "", []byte(`{"@type": "koral:token"}`)) // Valid minimal input
@@ -152,6 +163,11 @@
m, err := mapper.NewMapper([]tmconfig.MappingList{mappingList})
require.NoError(t, err)
+ // Create mock config for testing
+ mockConfig := &tmconfig.MappingLists{
+ Lists: []tmconfig.MappingList{mappingList},
+ }
+
// Create fiber app
app := fiber.New(fiber.Config{
DisableStartupMessage: true,
@@ -169,7 +185,7 @@
},
BodyLimit: maxInputLength,
})
- setupRoutes(app, m)
+ setupRoutes(app, m, mockConfig)
tests := []struct {
name string
diff --git a/cmd/termmapper/main.go b/cmd/termmapper/main.go
index 9d45bbc..4ba3dff 100644
--- a/cmd/termmapper/main.go
+++ b/cmd/termmapper/main.go
@@ -26,6 +26,14 @@
LogLevel string `kong:"short='l',default='info',help='Log level (debug, info, warn, error)'"`
}
+// TemplateData holds data for the Kalamar plugin template
+type TemplateData struct {
+ Title string
+ Version string
+ Description string
+ MappingIDs []string
+}
+
func parseConfig() *appConfig {
cfg := &appConfig{}
ctx := kong.Parse(cfg,
@@ -78,7 +86,7 @@
})
// Set up routes
- setupRoutes(app, m)
+ setupRoutes(app, m, yamlConfig)
// Start server
go func() {
@@ -100,7 +108,7 @@
}
}
-func setupRoutes(app *fiber.App, m *mapper.Mapper) {
+func setupRoutes(app *fiber.App, m *mapper.Mapper, yamlConfig *config.MappingLists) {
// Health check endpoint
app.Get("/health", func(c *fiber.Ctx) error {
return c.SendString("OK")
@@ -108,6 +116,9 @@
// Transformation endpoint
app.Post("/:map/query", handleTransform(m))
+
+ // Kalamar plugin endpoint
+ app.Get("/kalamarplugin", handleKalamarPlugin(yamlConfig))
}
func handleTransform(m *mapper.Mapper) fiber.Handler {
@@ -206,3 +217,81 @@
return nil
}
+
+func handleKalamarPlugin(yamlConfig *config.MappingLists) fiber.Handler {
+ return func(c *fiber.Ctx) error {
+ // Get list of available mapping IDs
+ var mappingIDs []string
+ for _, list := range yamlConfig.Lists {
+ mappingIDs = append(mappingIDs, list.ID)
+ }
+
+ // Prepare template data
+ data := TemplateData{
+ Title: "KoralPipe TermMapper - Kalamar Plugin",
+ Version: "1.0.0",
+ Description: "A KortalPipe web service for transforming JSON objects using term mapping rules.",
+ MappingIDs: mappingIDs,
+ }
+
+ // Generate HTML
+ html := generateKalamarPluginHTML(data)
+
+ c.Set("Content-Type", "text/html")
+ return c.SendString(html)
+ }
+}
+
+// generateKalamarPluginHTML creates the HTML template for the Kalamar plugin page
+// This function can be easily modified to change the appearance and content
+func generateKalamarPluginHTML(data TemplateData) string {
+ html := `<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <title>` + data.Title + `</title>
+</head>
+<body>
+ <div class="container">
+ <h1>` + data.Title + `</h1>
+
+ <div>
+ <h2>Plugin Information</h2>
+ <p><strong>Version:</strong> ` + data.Version + `</p>
+ <p><strong>Description:</strong> ` + data.Description + `</p>
+ </div>
+
+ <div class="plugin-info">
+ <h2>Available API Endpoints</h2>
+ <div class="api-endpoint">
+ <strong>POST</strong> /:map/query?dir=atob&foundryA=&foundryB=&layerA=&layerB=
+ <br><small>Transform JSON objects using term mapping rules</small>
+ </div>
+ <div class="api-endpoint">
+ <strong>GET</strong> /health
+ <br><small>Health check endpoint</small>
+ </div>
+ <div class="api-endpoint">
+ <strong>GET</strong> /kalamarplugin
+ <br><small>This entry point for Kalamar integration</small>
+ </div>
+ </div>
+
+ <div class="plugin-info">
+ <h2>Available Term Mappings</h2>
+ <ul>`
+
+ for _, id := range data.MappingIDs {
+ html += `
+ <li>` + id + `</li>`
+ }
+
+ html += `
+ </ul>
+ </div>
+</body>
+</html>`
+
+ return html
+}
diff --git a/cmd/termmapper/main_test.go b/cmd/termmapper/main_test.go
index 07bd176..2cbc4a3 100644
--- a/cmd/termmapper/main_test.go
+++ b/cmd/termmapper/main_test.go
@@ -33,9 +33,14 @@
m, err := mapper.NewMapper([]tmconfig.MappingList{mappingList})
require.NoError(t, err)
+ // Create mock config for testing
+ mockConfig := &tmconfig.MappingLists{
+ Lists: []tmconfig.MappingList{mappingList},
+ }
+
// Create fiber app
app := fiber.New()
- setupRoutes(app, m)
+ setupRoutes(app, m, mockConfig)
tests := []struct {
name string
@@ -263,9 +268,14 @@
m, err := mapper.NewMapper([]tmconfig.MappingList{mappingList})
require.NoError(t, err)
+ // Create mock config for testing
+ mockConfig := &tmconfig.MappingLists{
+ Lists: []tmconfig.MappingList{mappingList},
+ }
+
// Create fiber app
app := fiber.New()
- setupRoutes(app, m)
+ setupRoutes(app, m, mockConfig)
// Test health endpoint
req := httptest.NewRequest(http.MethodGet, "/health", nil)
@@ -277,4 +287,15 @@
body, err := io.ReadAll(resp.Body)
require.NoError(t, err)
assert.Equal(t, "OK", string(body))
+
+ req = httptest.NewRequest(http.MethodGet, "/kalamarplugin", nil)
+ resp, err = app.Test(req)
+ require.NoError(t, err)
+ defer resp.Body.Close()
+
+ assert.Equal(t, http.StatusOK, resp.StatusCode)
+ body, err = io.ReadAll(resp.Body)
+ require.NoError(t, err)
+ assert.Contains(t, string(body), "KoralPipe TermMapper - Kalamar Plugin")
+
}