1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package org.opencastproject.inspection.ffmpeg.endpoints;
23
24 import org.opencastproject.inspection.api.MediaInspectionService;
25 import org.opencastproject.inspection.api.util.Options;
26 import org.opencastproject.job.api.JaxbJob;
27 import org.opencastproject.job.api.Job;
28 import org.opencastproject.job.api.JobProducer;
29 import org.opencastproject.mediapackage.MediaPackageElementParser;
30 import org.opencastproject.rest.AbstractJobProducerEndpoint;
31 import org.opencastproject.serviceregistry.api.ServiceRegistry;
32 import org.opencastproject.util.doc.rest.RestParameter;
33 import org.opencastproject.util.doc.rest.RestQuery;
34 import org.opencastproject.util.doc.rest.RestResponse;
35 import org.opencastproject.util.doc.rest.RestService;
36
37 import org.osgi.service.component.ComponentContext;
38 import org.osgi.service.component.annotations.Activate;
39 import org.osgi.service.component.annotations.Component;
40 import org.osgi.service.component.annotations.Reference;
41 import org.osgi.service.component.annotations.ReferenceCardinality;
42 import org.osgi.service.component.annotations.ReferencePolicy;
43 import org.osgi.service.jaxrs.whiteboard.propertytypes.JaxrsResource;
44 import org.slf4j.Logger;
45 import org.slf4j.LoggerFactory;
46
47 import java.net.URI;
48
49 import javax.servlet.http.HttpServletResponse;
50 import javax.ws.rs.FormParam;
51 import javax.ws.rs.GET;
52 import javax.ws.rs.POST;
53 import javax.ws.rs.Path;
54 import javax.ws.rs.Produces;
55 import javax.ws.rs.QueryParam;
56 import javax.ws.rs.core.MediaType;
57 import javax.ws.rs.core.Response;
58
59
60
61
62 @Path("/inspection")
63 @RestService(
64 name = "mediainspection",
65 title = "Media Inspection Service",
66 abstractText = "This service extracts technical metadata from media files.",
67 notes = {
68 "All paths above are relative to the REST endpoint base (something like http://your.server/files)",
69 "If the service is down or not working it will return a status 503, this means the the underlying service is "
70 + "not working and is either restarting or has failed",
71 "A status code 500 means a general failure has occurred which is not recoverable and was not anticipated. In "
72 + "other words, there is a bug! You should file an error report with your server logs from the time "
73 + "when the error occurred: "
74 + "<a href=\"https://github.com/opencast/opencast/issues\">Opencast Issue Tracker</a>" })
75 @Component(
76 property = {
77 "service.description=Media Inspection REST Endpoint",
78 "opencast.service.type=org.opencastproject.inspection",
79 "opencast.service.path=/inspection",
80 "opencast.service.jobproducer=true"
81 },
82 immediate = true,
83 service = { MediaInspectionRestEndpoint.class }
84 )
85 @JaxrsResource
86 public class MediaInspectionRestEndpoint extends AbstractJobProducerEndpoint {
87
88
89 private static final Logger logger = LoggerFactory.getLogger(MediaInspectionRestEndpoint.class);
90
91
92 protected MediaInspectionService service;
93
94
95 protected ServiceRegistry serviceRegistry = null;
96
97
98
99
100
101
102
103 @Reference
104 protected void setServiceRegistry(ServiceRegistry serviceRegistry) {
105 this.serviceRegistry = serviceRegistry;
106 }
107
108
109
110
111
112
113
114 @Reference(cardinality = ReferenceCardinality.OPTIONAL, policy = ReferencePolicy.DYNAMIC)
115 public void setService(MediaInspectionService service) {
116 this.service = service;
117 }
118
119
120
121
122
123
124 public void unsetService(MediaInspectionService service) {
125 if (this.service == service) {
126 this.service = null;
127 }
128 }
129
130
131
132
133
134
135
136 @Activate
137 public void activate(ComponentContext cc) {
138
139 }
140
141 @GET
142 @Produces(MediaType.TEXT_XML)
143 @Path("inspect")
144 @RestQuery(
145 name = "inspect",
146 description = "Analyze a given media file",
147 restParameters = {
148 @RestParameter(description = "Location of the media file.", isRequired = false, name = "uri",
149 type = RestParameter.Type.STRING),
150 @RestParameter(description = "Options passed to media inspection service", isRequired = false,
151 name = "options", type = RestParameter.Type.STRING)
152 },
153 responses = {
154 @RestResponse(description = "XML encoded receipt is returned.", responseCode = HttpServletResponse.SC_OK),
155 @RestResponse(description = "Service unavailabe or not currently present",
156 responseCode = HttpServletResponse.SC_SERVICE_UNAVAILABLE),
157 @RestResponse(description = "Problem retrieving media file or invalid media file or URL.",
158 responseCode = HttpServletResponse.SC_INTERNAL_SERVER_ERROR)
159 },
160 returnDescription = "Returns a receipt to check on the status and outcome of the job")
161 public Response inspectTrack(@QueryParam("uri") URI uri, @QueryParam("options") String options) {
162 checkNotNull(service);
163 try {
164 Job job = service.inspect(uri, Options.fromJson(options));
165 return Response.ok(new JaxbJob(job)).build();
166 } catch (Exception e) {
167 logger.info("Unable to inspect track {}: {}", uri, e.getMessage());
168 return Response.serverError().build();
169 }
170 }
171
172 @POST
173 @Produces(MediaType.TEXT_XML)
174 @Path("enrich")
175 @RestQuery(
176 name = "enrich",
177 description = "Analyze and add missing metadata of a given media file",
178 restParameters = {
179 @RestParameter(description = "MediaPackage Element, that should be enriched with metadata ",
180 isRequired = true, name = "mediaPackageElement", type = RestParameter.Type.TEXT),
181 @RestParameter(description = "Should the existing metadata values remain", isRequired = true,
182 name = "override", type = RestParameter.Type.BOOLEAN),
183 @RestParameter(description = "Options passed to media inspection service", isRequired = false,
184 name = "options", type = RestParameter.Type.STRING)
185 },
186 responses = {
187 @RestResponse(description = "XML encoded receipt is returned.", responseCode = HttpServletResponse.SC_OK),
188 @RestResponse(description = "Service unavailabe or not currently present",
189 responseCode = HttpServletResponse.SC_SERVICE_UNAVAILABLE),
190 @RestResponse(description = "Problem retrieving media file or invalid media file or URL.",
191 responseCode = HttpServletResponse.SC_INTERNAL_SERVER_ERROR)
192 },
193 returnDescription = "Return a receipt to check on the status and outcome of the job")
194 public Response enrichTrack(@FormParam("mediaPackageElement") String mediaPackageElement,
195 @FormParam("override") boolean override, @FormParam("options") String options) {
196 checkNotNull(service);
197 try {
198 Job job = service.enrich(MediaPackageElementParser.getFromXml(mediaPackageElement), override,
199 Options.fromJson(options));
200 return Response.ok(new JaxbJob(job)).build();
201 } catch (Exception e) {
202 logger.info("Unable to enrich track {}: {}", mediaPackageElement, e.getMessage());
203 return Response.serverError().build();
204 }
205 }
206
207
208
209
210
211
212 @Override
213 public JobProducer getService() {
214 if (service instanceof JobProducer) {
215 return (JobProducer) service;
216 } else {
217 return null;
218 }
219 }
220
221
222
223
224
225
226 @Override
227 public ServiceRegistry getServiceRegistry() {
228 return serviceRegistry;
229 }
230
231
232
233
234
235
236
237 protected void checkNotNull(Object... services) {
238 if (services != null) {
239 for (Object object : services) {
240 if (object == null) {
241 throw new javax.ws.rs.WebApplicationException(javax.ws.rs.core.Response.Status.SERVICE_UNAVAILABLE);
242 }
243 }
244 }
245 }
246
247 }