Skip to content

Commit 947f67f

Browse files
committed
pipeline: add basic discovery
Add Pipeline API allowing the web client to retrieve the name of a given pipeline, which is know shown as a side card in the workflow page.
1 parent 6577882 commit 947f67f

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

69 files changed

+2620
-488
lines changed

internal/api/api.go

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,11 @@ import (
88

99
"github.com/artefactual-labs/enduro/internal/api/gen/collection"
1010
collectionsvr "github.com/artefactual-labs/enduro/internal/api/gen/http/collection/server"
11+
pipelinesvr "github.com/artefactual-labs/enduro/internal/api/gen/http/pipeline/server"
1112
swaggersvr "github.com/artefactual-labs/enduro/internal/api/gen/http/swagger/server"
13+
"github.com/artefactual-labs/enduro/internal/api/gen/pipeline"
1214
intcol "github.com/artefactual-labs/enduro/internal/collection"
15+
intpipe "github.com/artefactual-labs/enduro/internal/pipeline"
1316
"github.com/artefactual-labs/enduro/ui"
1417

1518
"github.com/go-logr/logr"
@@ -18,14 +21,23 @@ import (
1821
goahttpmwr "goa.design/goa/v3/http/middleware"
1922
)
2023

21-
func HTTPServer(logger logr.Logger, config *Config, colsvc intcol.Service) *http.Server {
24+
func HTTPServer(
25+
logger logr.Logger, config *Config,
26+
pipesvc intpipe.Service,
27+
colsvc intcol.Service,
28+
) *http.Server {
2229
var dec = goahttp.RequestDecoder
2330
var enc = goahttp.ResponseEncoder
2431
var mux goahttp.Muxer = goahttp.NewMuxer()
2532

33+
// Pipeline service.
34+
var pipelineEndpoints *pipeline.Endpoints = pipeline.NewEndpoints(pipesvc)
35+
var pipelineErrorHandler = errorHandler(logger, "Pipeline error.")
36+
var pipelineServer *pipelinesvr.Server = pipelinesvr.New(pipelineEndpoints, mux, dec, enc, pipelineErrorHandler, nil)
37+
pipelinesvr.Mount(mux, pipelineServer)
38+
2639
// Collection service.
27-
var collectionService collection.Service = colsvc.Goa()
28-
var collectionEndpoints *collection.Endpoints = collection.NewEndpoints(collectionService)
40+
var collectionEndpoints *collection.Endpoints = collection.NewEndpoints(colsvc.Goa())
2941
var collectionErrorHandler = errorHandler(logger, "Collection error.")
3042
var collectionServer *collectionsvr.Server = collectionsvr.New(collectionEndpoints, mux, dec, enc, collectionErrorHandler, nil)
3143
// Intercept request in Download endpoint so we can serve the file directly.

internal/api/design/collection.go

Lines changed: 265 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,265 @@
1+
package design
2+
3+
import (
4+
. "goa.design/goa/v3/dsl"
5+
)
6+
7+
var _ = Service("collection", func() {
8+
Description("The collection service manages packages being transferred to Archivematica.")
9+
HTTP(func() {
10+
Path("/collection")
11+
})
12+
Method("list", func() {
13+
Description("List all stored collections")
14+
Payload(func() {
15+
Attribute("name", String)
16+
Attribute("original_id", String)
17+
Attribute("transfer_id", String, func() {
18+
Format(FormatUUID)
19+
})
20+
Attribute("aip_id", String, func() {
21+
Format(FormatUUID)
22+
})
23+
Attribute("pipeline_id", String, func() {
24+
Format(FormatUUID)
25+
})
26+
Attribute("earliest_created_time", String, func() {
27+
Format(FormatDateTime)
28+
})
29+
Attribute("latest_created_time", String, func() {
30+
Format(FormatDateTime)
31+
})
32+
Attribute("status", String, func() {
33+
EnumCollectionStatus()
34+
})
35+
Attribute("cursor", String, "Pagination cursor")
36+
})
37+
Result(PaginatedCollectionOf(StoredCollection))
38+
HTTP(func() {
39+
GET("/")
40+
Response(StatusOK)
41+
Params(func() {
42+
Param("name")
43+
Param("original_id")
44+
Param("transfer_id")
45+
Param("aip_id")
46+
Param("pipeline_id")
47+
Param("earliest_created_time")
48+
Param("latest_created_time")
49+
Param("status")
50+
Param("cursor")
51+
})
52+
})
53+
})
54+
Method("show", func() {
55+
Description("Show collection by ID")
56+
Payload(func() {
57+
Attribute("id", UInt, "Identifier of collection to show")
58+
Required("id")
59+
})
60+
Result(StoredCollection)
61+
Error("not_found", NotFound, "Collection not found")
62+
HTTP(func() {
63+
GET("/{id}")
64+
Response(StatusOK)
65+
Response("not_found", StatusNotFound)
66+
})
67+
})
68+
Method("delete", func() {
69+
Description("Delete collection by ID")
70+
Payload(func() {
71+
Attribute("id", UInt, "Identifier of collection to delete")
72+
Required("id")
73+
})
74+
Error("not_found", NotFound, "Collection not found")
75+
HTTP(func() {
76+
DELETE("/{id}")
77+
Response(StatusNoContent)
78+
Response("not_found", StatusNotFound)
79+
})
80+
})
81+
Method("cancel", func() {
82+
Description("Cancel collection processing by ID")
83+
Payload(func() {
84+
Attribute("id", UInt, "Identifier of collection to remove")
85+
Required("id")
86+
})
87+
Error("not_found", NotFound, "Collection not found")
88+
Error("not_running")
89+
HTTP(func() {
90+
POST("/{id}/cancel")
91+
Response(StatusOK)
92+
Response("not_found", StatusNotFound)
93+
Response("not_running", StatusBadRequest)
94+
})
95+
})
96+
Method("retry", func() {
97+
Description("Retry collection processing by ID")
98+
Payload(func() {
99+
Attribute("id", UInt, "Identifier of collection to retry")
100+
Required("id")
101+
})
102+
Error("not_found", NotFound, "Collection not found")
103+
Error("not_running")
104+
HTTP(func() {
105+
POST("/{id}/retry")
106+
Response(StatusOK)
107+
Response("not_found", StatusNotFound)
108+
Response("not_running", StatusBadRequest)
109+
})
110+
})
111+
Method("workflow", func() {
112+
Description("Retrieve workflow status by ID")
113+
Payload(func() {
114+
Attribute("id", UInt, "Identifier of collection to look up")
115+
Required("id")
116+
})
117+
Result(WorkflowStatus)
118+
Error("not_found", NotFound, "Collection not found")
119+
HTTP(func() {
120+
GET("/{id}/workflow")
121+
Response(StatusOK)
122+
Response("not_found", StatusNotFound)
123+
})
124+
})
125+
Method("download", func() {
126+
Description("Download collection by ID")
127+
Payload(func() {
128+
Attribute("id", UInt, "Identifier of collection to look up")
129+
Required("id")
130+
})
131+
Result(Bytes)
132+
Error("not_found", NotFound, "Collection not found")
133+
HTTP(func() {
134+
GET("/{id}/download")
135+
Response(StatusOK)
136+
Response("not_found", StatusNotFound)
137+
})
138+
})
139+
Method("decide", func() {
140+
Description("Make decision for a pending collection by ID")
141+
Payload(func() {
142+
Attribute("id", UInt, "Identifier of collection to look up")
143+
Attribute("option", String, "Decision option to proceed with")
144+
Required("id", "option")
145+
})
146+
Error("not_found", NotFound, "Collection not found")
147+
Error("not_valid")
148+
HTTP(func() {
149+
POST("/{id}/decision")
150+
Body(func() {
151+
Attribute("option")
152+
})
153+
Response(StatusOK)
154+
Response("not_found", StatusNotFound)
155+
Response("not_valid", StatusBadRequest)
156+
})
157+
})
158+
})
159+
160+
var _ = Service("swagger", func() {
161+
Description("The swagger service serves the API swagger definition.")
162+
HTTP(func() {
163+
Path("/swagger")
164+
})
165+
Files("/swagger.json", "internal/api/gen/http/openapi.json", func() {
166+
Description("JSON document containing the API swagger definition.")
167+
})
168+
})
169+
170+
var EnumCollectionStatus = func() {
171+
Enum("new", "in progress", "done", "error", "unknown", "queued", "pending", "abandoned")
172+
}
173+
174+
var Collection = Type("Collection", func() {
175+
Description("Collection describes a collection to be stored.")
176+
Attribute("name", String, "Name of the collection")
177+
Attribute("status", String, "Status of the collection", func() {
178+
EnumCollectionStatus()
179+
Default("new")
180+
})
181+
Attribute("workflow_id", String, "Identifier of processing workflow", func() {
182+
Format(FormatUUID)
183+
})
184+
Attribute("run_id", String, "Identifier of latest processing workflow run", func() {
185+
Format(FormatUUID)
186+
})
187+
Attribute("transfer_id", String, "Identifier of Archivematica transfer", func() {
188+
Format(FormatUUID)
189+
})
190+
Attribute("aip_id", String, "Identifier of Archivematica AIP", func() {
191+
Format(FormatUUID)
192+
})
193+
Attribute("original_id", String, "Identifier provided by the client")
194+
Attribute("pipeline_id", String, "Identifier of Archivematica pipeline", func() {
195+
Format(FormatUUID)
196+
})
197+
Attribute("created_at", String, "Creation datetime", func() {
198+
Format(FormatDateTime)
199+
})
200+
Attribute("started_at", String, "Start datetime", func() {
201+
Format(FormatDateTime)
202+
})
203+
Attribute("completed_at", String, "Completion datetime", func() {
204+
Format(FormatDateTime)
205+
})
206+
Required("id", "status", "created_at")
207+
})
208+
209+
var StoredCollection = ResultType("application/vnd.enduro.stored-collection", func() {
210+
Description("StoredPipeline describes a collection retrieved by the service.")
211+
Reference(Collection)
212+
Attributes(func() {
213+
Attribute("id", UInt, "Identifier of collection")
214+
Attribute("name")
215+
Attribute("status")
216+
Attribute("workflow_id")
217+
Attribute("run_id")
218+
Attribute("transfer_id")
219+
Attribute("aip_id")
220+
Attribute("original_id")
221+
Attribute("pipeline_id")
222+
Attribute("created_at")
223+
Attribute("started_at")
224+
Attribute("completed_at")
225+
})
226+
View("default", func() {
227+
Attribute("id")
228+
Attribute("name")
229+
Attribute("status")
230+
Attribute("workflow_id")
231+
Attribute("run_id")
232+
Attribute("transfer_id")
233+
Attribute("aip_id")
234+
Attribute("original_id")
235+
Attribute("pipeline_id")
236+
Attribute("created_at")
237+
Attribute("started_at")
238+
Attribute("completed_at")
239+
})
240+
Required("id", "status", "created_at")
241+
})
242+
243+
var WorkflowStatus = ResultType("application/vnd.enduro.collection-workflow-status", func() {
244+
Description("WorkflowStatus describes the processing workflow status of a collection.")
245+
Attribute("status", String) // TODO
246+
Attribute("history", CollectionOf(WorkflowHistoryEvent))
247+
})
248+
249+
var WorkflowHistoryEvent = ResultType("application/vnd.enduro.collection-workflow-history", func() {
250+
Description("WorkflowHistoryEvent describes a history event in Cadence.")
251+
Attributes(func() {
252+
Attribute("id", UInt, "Identifier of collection")
253+
Attribute("type", String, "Type of the event")
254+
Attribute("details", Any, "Contents of the event")
255+
})
256+
})
257+
258+
var NotFound = Type("NotFound", func() {
259+
Description("NotFound is the type returned when attempting to operate with a collection that does not exist.")
260+
Attribute("message", String, "Message of error", func() {
261+
Meta("struct:error:name")
262+
})
263+
Attribute("id", UInt, "Identifier of missing collection")
264+
Required("message", "id")
265+
})

0 commit comments

Comments
 (0)