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.adminui.endpoint;
23
24 import static org.opencastproject.adminui.endpoint.EndpointUtil.addRequestFiltersToQuery;
25 import static org.opencastproject.adminui.endpoint.EndpointUtil.generateJSONObject;
26
27 import org.opencastproject.adminui.exception.JsonCreationException;
28 import org.opencastproject.index.service.resources.list.query.AclsListQuery;
29 import org.opencastproject.index.service.resources.list.query.AgentsListQuery;
30 import org.opencastproject.index.service.resources.list.query.EventListQuery;
31 import org.opencastproject.index.service.resources.list.query.GroupsListQuery;
32 import org.opencastproject.index.service.resources.list.query.JobsListQuery;
33 import org.opencastproject.index.service.resources.list.query.SeriesListQuery;
34 import org.opencastproject.index.service.resources.list.query.ServersListQuery;
35 import org.opencastproject.index.service.resources.list.query.ServicesListQuery;
36 import org.opencastproject.index.service.resources.list.query.ThemesListQuery;
37 import org.opencastproject.index.service.resources.list.query.UsersListQuery;
38 import org.opencastproject.index.service.util.JSONUtils;
39 import org.opencastproject.index.service.util.RestUtils;
40 import org.opencastproject.list.api.ListProviderException;
41 import org.opencastproject.list.api.ListProvidersService;
42 import org.opencastproject.list.api.ResourceListQuery;
43 import org.opencastproject.list.impl.ListProviderNotFoundException;
44 import org.opencastproject.list.impl.ResourceListQueryImpl;
45 import org.opencastproject.security.api.SecurityService;
46 import org.opencastproject.util.doc.rest.RestParameter;
47 import org.opencastproject.util.doc.rest.RestQuery;
48 import org.opencastproject.util.doc.rest.RestResponse;
49 import org.opencastproject.util.doc.rest.RestService;
50
51 import org.apache.commons.lang3.StringUtils;
52 import org.json.simple.JSONArray;
53 import org.json.simple.JSONObject;
54 import org.osgi.framework.BundleContext;
55 import org.osgi.service.component.annotations.Component;
56 import org.osgi.service.component.annotations.Reference;
57 import org.osgi.service.jaxrs.whiteboard.propertytypes.JaxrsResource;
58 import org.slf4j.Logger;
59 import org.slf4j.LoggerFactory;
60
61 import java.util.Map;
62
63 import javax.servlet.http.HttpServletResponse;
64 import javax.ws.rs.GET;
65 import javax.ws.rs.Path;
66 import javax.ws.rs.PathParam;
67 import javax.ws.rs.Produces;
68 import javax.ws.rs.QueryParam;
69 import javax.ws.rs.core.Context;
70 import javax.ws.rs.core.HttpHeaders;
71 import javax.ws.rs.core.MediaType;
72 import javax.ws.rs.core.Response;
73
74 @Path("/admin-ng/resources")
75 @RestService(
76 name = "ResourceListsProviders",
77 title = "Admin UI - Resources List",
78 abstractText = "This service provides key-value list from different resources to use in the admin UI.",
79 notes = { "This service offers access to list providers for the admin UI.",
80 "<strong>Important:</strong> "
81 + "<em>This service is for exclusive use by the module admin-ui. Its API might change "
82 + "anytime without prior notice. Any dependencies other than the admin UI will be strictly ignored. "
83 + "DO NOT use this for integration of third-party applications.<em>"})
84 @Component(
85 immediate = true,
86 service = ListProvidersEndpoint.class,
87 property = {
88 "service.description=Admin UI - Resource List Provider Endpoint",
89 "opencast.service.type=org.opencastproject.adminui.ListProvidersEndpoint",
90 "opencast.service.path=/admin-ng/resources",
91 }
92 )
93 @JaxrsResource
94 public class ListProvidersEndpoint {
95
96 private static final Logger logger = LoggerFactory.getLogger(ListProvidersEndpoint.class);
97
98 public static final Response UNAUTHORIZED = Response.status(Response.Status.UNAUTHORIZED).build();
99 public static final Response NOT_FOUND = Response.status(Response.Status.NOT_FOUND).build();
100 public static final Response SERVER_ERROR = Response.serverError().build();
101 public static final Response NO_CONTENT = Response.noContent().build();
102
103 private SecurityService securityService;
104 private ListProvidersService listProvidersService;
105 private SeriesEndpoint seriesEndpoint;
106
107
108
109 private static final String PROP_KEY_USER_FILTER_REGEX = "org.opencastproject.adminui.filter.user.regex";
110 private static final String PROP_KEY_USER_FILTER_REGEX_DEFAULT = ".*";
111
112 protected void activate(BundleContext bundleContext) {
113 logger.info("Activate list provider service");
114 JSONUtils.setUserRegex(StringUtils.defaultIfBlank(
115 bundleContext.getProperty(PROP_KEY_USER_FILTER_REGEX),
116 PROP_KEY_USER_FILTER_REGEX_DEFAULT));
117 }
118
119
120 @Reference
121 public void setListProvidersService(ListProvidersService listProvidersService) {
122 this.listProvidersService = listProvidersService;
123 }
124
125
126 @Reference
127 public void setSecurityService(SecurityService securitySerivce) {
128 this.securityService = securitySerivce;
129 }
130
131
132 @Reference
133 public void setSeriesEndpoint(SeriesEndpoint seriesEndpoint) {
134 this.seriesEndpoint = seriesEndpoint;
135 }
136
137 @GET
138 @Path("{source}.json")
139 @Produces(MediaType.APPLICATION_JSON)
140 @RestQuery(
141 name = "list",
142 description = "Provides key-value list from the given source",
143 pathParameters = {
144 @RestParameter(name = "source", description = "The source for the key-value list", isRequired = true,
145 type = RestParameter.Type.STRING)
146 },
147 restParameters = {
148 @RestParameter(description = "The maximum number of items to return per page", isRequired = false,
149 name = "limit", type = RestParameter.Type.INTEGER),
150 @RestParameter(description = "The offset", isRequired = false, name = "offset",
151 type = RestParameter.Type.INTEGER),
152 @RestParameter(description = "Filters", isRequired = false, name = "filter",
153 type = RestParameter.Type.STRING)
154 },
155 responses = {
156 @RestResponse(description = "Returns the key-value list for the given source.",
157 responseCode = HttpServletResponse.SC_OK)
158 },
159 returnDescription = "")
160 public Response getList(@PathParam("source") final String source, @QueryParam("limit") final int limit,
161 @QueryParam("filter") final String filter, @QueryParam("offset") final int offset,
162 @Context HttpHeaders headers) {
163
164 ResourceListQueryImpl query = new ResourceListQueryImpl();
165 query.setLimit(limit);
166 query.setOffset(offset);
167 addRequestFiltersToQuery(filter, query);
168 Map<String, String> autocompleteList;
169 try {
170 autocompleteList = listProvidersService.getList(source, query, false);
171 } catch (ListProviderNotFoundException e) {
172 logger.debug("No list found for {}", source, e);
173 return NOT_FOUND;
174 } catch (ListProviderException e) {
175 logger.error("Server error when getting list from provider {}", source, e);
176 return SERVER_ERROR;
177 }
178
179 JSONObject jsonList;
180 try {
181 jsonList = generateJSONObject(autocompleteList);
182 } catch (JsonCreationException e) {
183 logger.error("Not able to generate resources list JSON from source {}", source, e);
184 return SERVER_ERROR;
185 }
186
187 return Response.ok(jsonList.toString()).build();
188 }
189
190 @GET
191 @Path("components.json")
192 @Produces(MediaType.APPLICATION_JSON)
193 @RestQuery(
194 name = "components",
195 description = "Provides a set of constants lists (right now only eventCommentReasons) for use in the admin UI",
196 responses = {
197 @RestResponse(description = "Returns a set of constants lists (right now only eventCommentReasons) for use "
198 + "in the admin UI", responseCode = HttpServletResponse.SC_OK)
199 },
200 returnDescription = "")
201 public Response getComponents(@Context HttpHeaders headers) {
202 String[] sources = { "eventCommentReasons" };
203 ResourceListQuery query = new ResourceListQueryImpl();
204
205 JSONObject list = new JSONObject();
206
207 for (String source : sources) {
208 if (listProvidersService.hasProvider(source)) {
209 JSONObject subList;
210 try {
211 subList = generateJSONObject(listProvidersService.getList(source, query, true));
212 list.put(source, subList);
213 } catch (JsonCreationException e) {
214 logger.error("Not able to generate resources list JSON from source {}", source, e);
215 return SERVER_ERROR;
216 } catch (ListProviderException e) {
217 logger.error("Not able to get list from provider {}", source, e);
218 return SERVER_ERROR;
219 }
220 } else {
221 return NOT_FOUND;
222 }
223 }
224
225 return Response.ok(list.toString()).build();
226 }
227
228 @GET
229 @Path("providers.json")
230 @Produces(MediaType.APPLICATION_JSON)
231 @RestQuery(
232 name = "availableProviders",
233 description = "Provides the list of the available list providers",
234 responses = {
235 @RestResponse(description = "Returns the availables list providers.",
236 responseCode = HttpServletResponse.SC_OK)
237 },
238 returnDescription = "")
239 public Response getAvailablesProviders(@Context HttpHeaders headers) {
240 JSONArray list = new JSONArray();
241
242 list.add(listProvidersService.getAvailableProviders());
243
244 return Response.ok(list.toString()).build();
245 }
246
247 @GET
248 @Path("{page}/filters.json")
249 @Produces(MediaType.APPLICATION_JSON)
250 @RestQuery(
251 name = "filters",
252 description = "Provides filters for the given page",
253 pathParameters = {
254 @RestParameter(name = "page", description = "The page for which the filters are required", isRequired = true,
255 type = RestParameter.Type.STRING)
256 },
257 responses = {
258 @RestResponse(description = "Returns the filters for the given page.",
259 responseCode = HttpServletResponse.SC_OK)
260 },
261 returnDescription = "")
262 public Response getFilters(@PathParam("page") final String page, @Context HttpHeaders headers)
263 throws ListProviderException {
264
265 ResourceListQuery query;
266
267 if ("series".equals(page)) {
268 query = new SeriesListQuery();
269 } else if ("events".equals(page)) {
270 query = new EventListQuery();
271 } else if ("jobs".equals(page)) {
272 query = new JobsListQuery();
273 } else if ("recordings".equals(page)) {
274 query = new AgentsListQuery();
275 } else if ("users".equals(page)) {
276 query = new UsersListQuery();
277 } else if ("groups".equals(page)) {
278 query = new GroupsListQuery();
279 } else if ("acls".equals(page)) {
280 query = new AclsListQuery();
281 } else if ("servers".equals(page)) {
282 query = new ServersListQuery();
283 } else if ("services".equals(page)) {
284 query = new ServicesListQuery();
285 } else if ("themes".equals(page)) {
286 query = new ThemesListQuery();
287 } else {
288 logger.debug("No filters defined for the page {}.", page);
289 return NO_CONTENT;
290 }
291
292 try {
293 if ("events".equals(page) && seriesEndpoint.getOnlySeriesWithWriteAccessEventsFilter()) {
294 Map<String, String> seriesWriteAccess = seriesEndpoint.getUserSeriesByAccess(true);
295 return RestUtils.okJson(JSONUtils.filtersToJSONSeriesWriteAccess(query, listProvidersService,
296 seriesWriteAccess));
297 } else {
298 return RestUtils.okJson(JSONUtils.filtersToJSON(query, listProvidersService,
299 securityService.getOrganization()));
300 }
301 } catch (ListProviderException e) {
302 logger.error("Not able to get list of options for the filters for the page {}", page, e);
303 return SERVER_ERROR;
304 }
305 }
306
307 }