1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package org.opencastproject.lti.endpoint;
22
23 import org.opencastproject.lti.service.api.LtiFileUpload;
24 import org.opencastproject.lti.service.api.LtiJob;
25 import org.opencastproject.lti.service.api.LtiService;
26 import org.opencastproject.security.api.TrustedHttpClient;
27 import org.opencastproject.security.api.UnauthorizedException;
28 import org.opencastproject.serviceregistry.api.RemoteBase;
29 import org.opencastproject.serviceregistry.api.ServiceRegistry;
30 import org.opencastproject.util.NotFoundException;
31
32 import com.google.gson.Gson;
33 import com.google.gson.reflect.TypeToken;
34
35 import org.apache.commons.io.IOUtils;
36 import org.apache.http.HttpResponse;
37 import org.apache.http.client.methods.HttpDelete;
38 import org.apache.http.client.methods.HttpGet;
39 import org.apache.http.client.methods.HttpPost;
40 import org.apache.http.client.methods.HttpRequestBase;
41 import org.apache.http.entity.mime.MultipartEntityBuilder;
42 import org.apache.http.entity.mime.content.InputStreamBody;
43 import org.osgi.service.component.annotations.Component;
44 import org.osgi.service.component.annotations.Reference;
45
46 import java.io.IOException;
47 import java.io.InputStreamReader;
48 import java.nio.charset.StandardCharsets;
49 import java.util.List;
50
51 import javax.ws.rs.core.Response;
52
53
54
55
56 @Component(
57 immediate = true,
58 service = LtiService.class,
59 property = {
60 "service.description=LTI Service Remote Service"
61 }
62 )
63 public class LtiServiceRemoteImpl extends RemoteBase implements LtiService {
64 private static final Gson gson = new Gson();
65
66 public LtiServiceRemoteImpl() {
67 super(LtiService.JOB_TYPE);
68 }
69
70 private HttpResponse safeGetResponse(final HttpRequestBase r) {
71 final HttpResponse response = getResponse(r);
72 if (response == null) {
73 throw new RuntimeException("No response from service");
74 }
75 return response;
76 }
77
78 @Override
79 public List<LtiJob> listJobs(final String seriesId) {
80 HttpResponse response = null;
81 try {
82 response = safeGetResponse(new HttpGet("/jobs?seriesId=" + seriesId));
83 return gson.fromJson(
84 new InputStreamReader(response.getEntity().getContent(), StandardCharsets.UTF_8),
85 new TypeToken<List<LtiJob>>() { }.getType());
86 } catch (IOException e) {
87 throw new RuntimeException("failed retrieving jobs", e);
88 } finally {
89 closeConnection(response);
90 }
91 }
92
93 @Override
94 public void upsertEvent(
95 final LtiFileUpload file,
96 final String captions,
97 final String captionFormat,
98 final String captionLanguage,
99 final String eventId,
100 final String seriesId,
101 final String metadataJson) {
102 final MultipartEntityBuilder entity = MultipartEntityBuilder.create();
103 entity.addTextBody("isPartOf", seriesId);
104 entity.addTextBody("metadata", metadataJson);
105 if (eventId != null) {
106 entity.addTextBody("eventId", eventId);
107 }
108 if (captions != null) {
109 entity.addTextBody("captions", captions);
110 }
111 if (captionFormat != null) {
112 entity.addTextBody("captionFormat", captionFormat);
113 }
114 if (captionLanguage != null) {
115 entity.addTextBody("captionLanguage", captionLanguage);
116 }
117 if (file != null) {
118 entity.addPart(file.getSourceName(), new InputStreamBody(file.getStream(), file.getSourceName()));
119 }
120 final HttpPost post = new HttpPost("/");
121 post.setEntity(entity.build());
122 closeConnection(safeGetResponse(post));
123 }
124
125 @Override
126 public void copyEventToSeries(final String eventId, final String seriesId) {
127 final HttpPost post = new HttpPost("/" + eventId + "/copy?seriesId=" + seriesId);
128 closeConnection(safeGetResponse(post));
129 }
130
131 @Override
132 public String getEventMetadata(final String eventId) throws NotFoundException, UnauthorizedException {
133 HttpResponse response = null;
134 try {
135 response = safeGetResponse(new HttpGet("/" + eventId + "/metadata"));
136 if (response.getStatusLine().getStatusCode() == Response.Status.NOT_FOUND.getStatusCode()) {
137 throw new NotFoundException("event not found: " + eventId);
138 }
139 if (response.getStatusLine().getStatusCode() == Response.Status.UNAUTHORIZED.getStatusCode()) {
140 throw new UnauthorizedException("not authorized to access event with ID " + eventId);
141 }
142 return IOUtils.toString(response.getEntity().getContent(), StandardCharsets.UTF_8);
143 } catch (IOException e) {
144 throw new RuntimeException("failed retrieving jobs", e);
145 } finally {
146 closeConnection(response);
147 }
148 }
149
150 @Override
151 public String getNewEventMetadata() {
152 HttpResponse response = null;
153 try {
154 response = safeGetResponse(new HttpGet("/new/metadata"));
155 return IOUtils.toString(response.getEntity().getContent(), StandardCharsets.UTF_8);
156 } catch (IOException e) {
157 throw new RuntimeException("failed retrieving jobs", e);
158 } finally {
159 closeConnection(response);
160 }
161 }
162
163 @Override
164 public void setEventMetadataJson(final String eventId, final String metadataJson)
165 throws NotFoundException, UnauthorizedException {
166 final MultipartEntityBuilder entity = MultipartEntityBuilder.create();
167 entity.addTextBody("metadata", metadataJson);
168 final HttpPost post = new HttpPost("/" + eventId + "/metadata");
169 post.setEntity(entity.build());
170 HttpResponse response = null;
171 try {
172 response = safeGetResponse(post);
173 if (response.getStatusLine().getStatusCode() == Response.Status.NOT_FOUND.getStatusCode()) {
174 throw new NotFoundException("event not found: " + eventId);
175 }
176 if (response.getStatusLine().getStatusCode() == Response.Status.UNAUTHORIZED.getStatusCode()) {
177 throw new UnauthorizedException("not authorized to access event with ID " + eventId);
178 }
179 } finally {
180 closeConnection(response);
181 }
182 }
183
184 @Override
185 public void delete(String eventId) {
186 final HttpDelete post = new HttpDelete("/" + eventId);
187 final HttpResponse response = getResponse(post, Response.Status.NO_CONTENT.getStatusCode());
188 if (response == null) {
189 throw new RuntimeException("No response from service");
190 }
191 }
192
193 @Reference
194 @Override
195 public void setTrustedHttpClient(TrustedHttpClient trustedHttpClient) {
196 super.setTrustedHttpClient(trustedHttpClient);
197 }
198
199 @Reference
200 @Override
201 public void setRemoteServiceManager(ServiceRegistry serviceRegistry) {
202 super.setRemoteServiceManager(serviceRegistry);
203 }
204
205 }