View Javadoc
1   package de.dlr.shepard.common.subscription.endpoints;
2   
3   import de.dlr.shepard.common.subscription.entities.Subscription;
4   import de.dlr.shepard.common.subscription.io.EventIO;
5   import de.dlr.shepard.common.subscription.io.SubscriptionIO;
6   import de.dlr.shepard.common.subscription.services.SubscriptionService;
7   import de.dlr.shepard.common.util.Constants;
8   import jakarta.enterprise.context.RequestScoped;
9   import jakarta.inject.Inject;
10  import jakarta.validation.Valid;
11  import jakarta.validation.constraints.NotBlank;
12  import jakarta.validation.constraints.NotNull;
13  import jakarta.validation.constraints.PositiveOrZero;
14  import jakarta.ws.rs.Consumes;
15  import jakarta.ws.rs.DELETE;
16  import jakarta.ws.rs.GET;
17  import jakarta.ws.rs.POST;
18  import jakarta.ws.rs.Path;
19  import jakarta.ws.rs.PathParam;
20  import jakarta.ws.rs.Produces;
21  import jakarta.ws.rs.core.MediaType;
22  import jakarta.ws.rs.core.Response;
23  import jakarta.ws.rs.core.Response.Status;
24  import java.util.ArrayList;
25  import org.eclipse.microprofile.openapi.annotations.Operation;
26  import org.eclipse.microprofile.openapi.annotations.callbacks.Callback;
27  import org.eclipse.microprofile.openapi.annotations.callbacks.CallbackOperation;
28  import org.eclipse.microprofile.openapi.annotations.enums.SchemaType;
29  import org.eclipse.microprofile.openapi.annotations.links.Link;
30  import org.eclipse.microprofile.openapi.annotations.links.LinkParameter;
31  import org.eclipse.microprofile.openapi.annotations.media.Content;
32  import org.eclipse.microprofile.openapi.annotations.media.Schema;
33  import org.eclipse.microprofile.openapi.annotations.parameters.Parameter;
34  import org.eclipse.microprofile.openapi.annotations.parameters.RequestBody;
35  import org.eclipse.microprofile.openapi.annotations.responses.APIResponse;
36  import org.eclipse.microprofile.openapi.annotations.tags.Tag;
37  
38  @Produces(MediaType.APPLICATION_JSON)
39  @Consumes(MediaType.APPLICATION_JSON)
40  @Path(Constants.USERS + "/{" + Constants.USERNAME + "}/" + Constants.SUBSCRIPTIONS)
41  @RequestScoped
42  public class SubscriptionRest {
43  
44    @Inject
45    SubscriptionService subscriptionService;
46  
47    @GET
48    @Tag(name = Constants.SUBSCRIPTION)
49    @Operation(description = "Get all subscriptions")
50    @APIResponse(
51      description = "ok",
52      responseCode = "200",
53      content = @Content(schema = @Schema(type = SchemaType.ARRAY, implementation = SubscriptionIO.class))
54    )
55    @APIResponse(responseCode = "400", description = "bad request")
56    @APIResponse(responseCode = "401", description = "not authorized")
57    @APIResponse(responseCode = "403", description = "forbidden")
58    @APIResponse(responseCode = "404", description = "not found")
59    @Parameter(name = Constants.USERNAME)
60    public Response getAllSubscriptions(@PathParam(Constants.USERNAME) @NotBlank String username) {
61      var subscriptions = subscriptionService.getAllSubscriptions(username);
62      var result = new ArrayList<SubscriptionIO>(subscriptions.size());
63      for (var sub : subscriptions) {
64        result.add(new SubscriptionIO(sub));
65      }
66      return Response.ok(result).build();
67    }
68  
69    @GET
70    @Path("/{" + Constants.SUBSCRIPTION_ID + "}")
71    @Tag(name = Constants.SUBSCRIPTION)
72    @Operation(description = "Get subscription")
73    @APIResponse(
74      description = "ok",
75      responseCode = "200",
76      content = @Content(schema = @Schema(implementation = SubscriptionIO.class))
77    )
78    @APIResponse(responseCode = "400", description = "bad request")
79    @APIResponse(responseCode = "401", description = "not authorized")
80    @APIResponse(responseCode = "403", description = "forbidden")
81    @APIResponse(responseCode = "404", description = "not found")
82    @Parameter(name = Constants.USERNAME)
83    @Parameter(name = Constants.SUBSCRIPTION_ID)
84    public Response getSubscription(
85      @PathParam(Constants.USERNAME) @NotBlank String username,
86      @PathParam(Constants.SUBSCRIPTION_ID) @NotNull @PositiveOrZero Long subscriptionId
87    ) {
88      Subscription subscription = subscriptionService.getSubscription(subscriptionId, username);
89      return Response.ok(new SubscriptionIO(subscription)).build();
90    }
91  
92    @POST
93    @Tag(name = Constants.SUBSCRIPTION)
94    @Operation(description = "Create a new subscription")
95    @APIResponse(
96      description = "created",
97      responseCode = "201",
98      content = @Content(schema = @Schema(implementation = SubscriptionIO.class)),
99      links = @Link(
100       name = "unsubscribe",
101       operationId = "deleteSubscription",
102       parameters = @LinkParameter(name = Constants.SUBSCRIPTION_ID, expression = "$response.body#/id")
103     )
104   )
105   @APIResponse(responseCode = "400", description = "bad request")
106   @APIResponse(responseCode = "401", description = "not authorized")
107   @APIResponse(responseCode = "403", description = "forbidden")
108   @APIResponse(responseCode = "404", description = "not found")
109   @Callback(
110     name = "SubscriptionIO",
111     operations = @CallbackOperation(
112       summary = "Notify the client about an event",
113       method = "post",
114       responses = @APIResponse(responseCode = "200", description = "Notification received"),
115       requestBody = @RequestBody(
116         description = "Notification about an event",
117         content = @Content(schema = @Schema(implementation = EventIO.class)),
118         required = true
119       )
120     ),
121     callbackUrlExpression = "{$request.body#/callbackUrl}"
122   )
123   @Parameter(name = Constants.USERNAME)
124   public Response createSubscription(
125     @PathParam(Constants.USERNAME) @NotBlank String username,
126     @RequestBody(
127       required = true,
128       content = @Content(schema = @Schema(implementation = SubscriptionIO.class))
129     ) @Valid SubscriptionIO subscription
130   ) {
131     Subscription created = subscriptionService.createSubscription(subscription, username);
132     return Response.status(Status.CREATED).entity(new SubscriptionIO(created)).build();
133   }
134 
135   @DELETE
136   @Path("/{" + Constants.SUBSCRIPTION_ID + "}")
137   @Tag(name = Constants.SUBSCRIPTION)
138   @Operation(description = "Delete subscription")
139   @APIResponse(description = "deleted", responseCode = "204")
140   @APIResponse(responseCode = "400", description = "bad request")
141   @APIResponse(responseCode = "401", description = "not authorized")
142   @APIResponse(responseCode = "403", description = "forbidden")
143   @APIResponse(responseCode = "404", description = "not found")
144   @Parameter(name = Constants.USERNAME)
145   @Parameter(name = Constants.SUBSCRIPTION_ID)
146   public Response deleteSubscription(
147     @PathParam(Constants.USERNAME) @NotBlank String username,
148     @PathParam(Constants.SUBSCRIPTION_ID) @NotNull @PositiveOrZero Long subscriptionId
149   ) {
150     subscriptionService.deleteSubscription(subscriptionId, username);
151     return Response.status(Status.NO_CONTENT).build();
152   }
153 }