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.capture.admin.impl;
23
24 import org.opencastproject.capture.CaptureParameters;
25 import org.opencastproject.capture.admin.api.Agent;
26
27 import org.slf4j.Logger;
28 import org.slf4j.LoggerFactory;
29
30 import java.io.IOException;
31 import java.io.StringReader;
32 import java.io.StringWriter;
33 import java.util.HashMap;
34 import java.util.HashSet;
35 import java.util.Properties;
36 import java.util.Set;
37
38 import javax.persistence.CollectionTable;
39 import javax.persistence.Column;
40 import javax.persistence.ElementCollection;
41 import javax.persistence.Entity;
42 import javax.persistence.Id;
43 import javax.persistence.IdClass;
44 import javax.persistence.Index;
45 import javax.persistence.JoinColumn;
46 import javax.persistence.Lob;
47 import javax.persistence.NamedQueries;
48 import javax.persistence.NamedQuery;
49 import javax.persistence.PostLoad;
50 import javax.persistence.Table;
51 import javax.persistence.Transient;
52 import javax.persistence.UniqueConstraint;
53
54
55
56
57 @Entity @IdClass(AgentImplId.class)
58 @Table(name = "oc_capture_agent_state")
59 @NamedQueries({
60 @NamedQuery(name = "Agent.get", query = "select a from AgentImpl a where a.name = :id and a.organization = :org"),
61 @NamedQuery(name = "Agent.byOrganization", query = "SELECT a FROM AgentImpl a where a.organization = :org")
62 })
63 public class AgentImpl implements Agent {
64
65 private static final Logger log = LoggerFactory.getLogger(AgentImpl.class);
66
67
68
69
70 @Id
71 @Column(name = "id", length = 128)
72 protected String name;
73
74
75
76
77 @Lob
78 @Column(name = "state", nullable = false, length = 65535)
79 protected String state;
80
81
82
83
84 @Lob
85 @Column(name = "url", length = 65535)
86 protected String url;
87
88 @Id
89 @Column(name = "organization", length = 128)
90 protected String organization;
91
92
93
94
95
96 @Column(name = "last_heard_from", nullable = false)
97 protected Long lastHeardFrom;
98
99
100 @ElementCollection
101 @Column(name = "role", nullable = false)
102 @CollectionTable(
103 name = "oc_capture_agent_role",
104 indexes = {
105 @Index(name = "IX_oc_capture_agent_role_pk", columnList = "id, organization")
106 }, uniqueConstraints = {
107 @UniqueConstraint(name = "UNQ_capture_agent_role_id_org_role", columnNames = {"id", "organization", "role"})
108 }, joinColumns = {
109 @JoinColumn(name = "id", referencedColumnName = "id", nullable = false),
110 @JoinColumn(name = "organization", referencedColumnName = "organization", nullable = false)
111 })
112 protected Set<String> schedulerRoles = new HashSet<>();
113
114
115
116
117
118 @Lob
119 @Column(name = "configuration", nullable = true, length = 65535)
120 protected String configurationString;
121
122
123 @Transient
124 private Properties capabilitiesProperties;
125
126
127 @Transient
128 private Properties configurationProperties;
129
130
131
132
133 public AgentImpl() {
134 };
135
136
137
138
139
140
141
142
143
144
145
146
147
148 public AgentImpl(String agentName, String organization, String agentState, String agentUrl,
149 Properties configuration) {
150 name = agentName;
151 this.setState(agentState);
152 this.setUrl(agentUrl);
153 this.setOrganization(organization);
154
155 setConfiguration(configuration);
156 }
157
158
159
160
161
162
163 public String getName() {
164 return name;
165 }
166
167
168
169
170
171
172 public void setState(String newState) {
173 state = newState;
174 setLastHeardFrom(System.currentTimeMillis());
175 }
176
177
178
179
180
181
182 public String getState() {
183 return state;
184 }
185
186
187
188
189
190
191 public void setUrl(String agentUrl) {
192 url = agentUrl;
193 }
194
195
196
197
198
199
200 public String getUrl() {
201 return url;
202 }
203
204
205
206
207
208
209 public void setLastHeardFrom(Long time) {
210 lastHeardFrom = time;
211 }
212
213
214
215
216
217
218 public Long getLastHeardFrom() {
219 return lastHeardFrom;
220 }
221
222
223
224
225
226
227 public Properties getCapabilities() {
228 return capabilitiesProperties;
229 }
230
231
232
233
234
235
236 public Properties getConfiguration() {
237 return configurationProperties;
238 }
239
240
241
242
243 public Set<String> getSchedulerRoles() {
244 return schedulerRoles;
245 }
246
247
248
249
250
251 public void setSchedulerRoles(Set<String> schedulerRoles) {
252 this.schedulerRoles = schedulerRoles;
253 }
254
255
256
257
258 public String getOrganization() {
259 return organization;
260 }
261
262
263
264
265
266 public void setOrganization(String organization) {
267 this.organization = organization;
268 }
269
270
271
272
273
274
275 public void setConfiguration(Properties configuration) {
276 if (configuration == null) {
277 return;
278 }
279
280
281 configurationProperties = configuration;
282 try {
283 StringWriter sw = new StringWriter();
284 configuration.store(sw, "");
285 this.configurationString = sw.toString();
286 } catch (IOException e) {
287 log.warn("Unable to store agent " + "'s capabilities to the database, IO exception occurred.", e);
288 }
289
290
291
292 capabilitiesProperties = new Properties();
293
294 String names = configuration.getProperty(CaptureParameters.CAPTURE_DEVICE_NAMES);
295 if (names == null) {
296 log.debug("Capture agent '{}' failed to provide device names ({})", name, CaptureParameters.CAPTURE_DEVICE_NAMES);
297 return;
298 }
299
300 capabilitiesProperties.put(CaptureParameters.CAPTURE_DEVICE_NAMES, names);
301
302 String[] friendlyNames = names.split(",");
303 HashMap<String, Integer> propertyCounts = new HashMap<String, Integer>();
304 for (String name : friendlyNames) {
305 propertyCounts.put(name, 0);
306 }
307
308
309 for (String key : configuration.stringPropertyNames()) {
310
311 for (String name : friendlyNames) {
312 String check = CaptureParameters.CAPTURE_DEVICE_PREFIX + name;
313
314 if (key.contains(check)) {
315 String property = configuration.getProperty(key);
316 if (property == null) {
317 log.error("Unable to expand variable in value for key {}, returning null!", key);
318 capabilitiesProperties = null;
319 return;
320 }
321 capabilitiesProperties.setProperty(key, property);
322 propertyCounts.put(name, propertyCounts.get(name) + 1);
323 }
324 }
325 }
326 }
327
328
329
330
331 @SuppressWarnings("unused")
332 @PostLoad
333 private void loadCaps() {
334 configurationProperties = new Properties();
335 if (configurationString == null) {
336 log.info("No configuration properties set yet for '{}'", name);
337 } else {
338 try {
339 configurationProperties.load(new StringReader(this.configurationString));
340 this.setConfiguration(configurationProperties);
341 } catch (IOException e) {
342 log.warn("Unable to load agent " + name + "'s capabilities, IO exception occurred.", e);
343 }
344 }
345 }
346
347
348
349
350
351
352 @Override
353 public boolean equals(Object o) {
354 if (this == o) {
355 return true;
356 }
357 if (o instanceof AgentImpl) {
358 return name.equals(((AgentImpl) o).name);
359 } else {
360 return false;
361 }
362 }
363
364
365
366
367
368
369 @Override
370 public int hashCode() {
371 return name.hashCode();
372 }
373 }