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(name = "oc_capture_agent_role", indexes = {
103 @Index(name = "IX_oc_capture_agent_role_pk", columnList = "id, organization")
104 }, uniqueConstraints = {
105 @UniqueConstraint(name = "UNQ_capture_agent_role_id_org_role", columnNames = {"id", "organization", "role"})
106 }, joinColumns = {
107 @JoinColumn(name = "id", referencedColumnName = "id", nullable = false),
108 @JoinColumn(name = "organization", referencedColumnName = "organization", nullable = false) })
109 protected Set<String> schedulerRoles = new HashSet<>();
110
111
112
113
114
115 @Lob
116 @Column(name = "configuration", nullable = true, length = 65535)
117 protected String configurationString;
118
119
120 @Transient
121 private Properties capabilitiesProperties;
122
123
124 @Transient
125 private Properties configurationProperties;
126
127
128
129
130 public AgentImpl() {
131 };
132
133
134
135
136
137
138
139
140
141
142
143
144
145 public AgentImpl(String agentName, String organization, String agentState, String agentUrl, Properties configuration) {
146 name = agentName;
147 this.setState(agentState);
148 this.setUrl(agentUrl);
149 this.setOrganization(organization);
150
151 setConfiguration(configuration);
152 }
153
154
155
156
157
158
159 public String getName() {
160 return name;
161 }
162
163
164
165
166
167
168 public void setState(String newState) {
169 state = newState;
170 setLastHeardFrom(System.currentTimeMillis());
171 }
172
173
174
175
176
177
178 public String getState() {
179 return state;
180 }
181
182
183
184
185
186
187 public void setUrl(String agentUrl) {
188 url = agentUrl;
189 }
190
191
192
193
194
195
196 public String getUrl() {
197 return url;
198 }
199
200
201
202
203
204
205 public void setLastHeardFrom(Long time) {
206 lastHeardFrom = time;
207 }
208
209
210
211
212
213
214 public Long getLastHeardFrom() {
215 return lastHeardFrom;
216 }
217
218
219
220
221
222
223 public Properties getCapabilities() {
224 return capabilitiesProperties;
225 }
226
227
228
229
230
231
232 public Properties getConfiguration() {
233 return configurationProperties;
234 }
235
236
237
238
239 public Set<String> getSchedulerRoles() {
240 return schedulerRoles;
241 }
242
243
244
245
246
247 public void setSchedulerRoles(Set<String> schedulerRoles) {
248 this.schedulerRoles = schedulerRoles;
249 }
250
251
252
253
254 public String getOrganization() {
255 return organization;
256 }
257
258
259
260
261
262 public void setOrganization(String organization) {
263 this.organization = organization;
264 }
265
266
267
268
269
270
271 public void setConfiguration(Properties configuration) {
272 if (configuration == null) {
273 return;
274 }
275
276
277 configurationProperties = configuration;
278 try {
279 StringWriter sw = new StringWriter();
280 configuration.store(sw, "");
281 this.configurationString = sw.toString();
282 } catch (IOException e) {
283 log.warn("Unable to store agent " + "'s capabilities to the database, IO exception occurred.", e);
284 }
285
286
287
288 capabilitiesProperties = new Properties();
289
290 String names = configuration.getProperty(CaptureParameters.CAPTURE_DEVICE_NAMES);
291 if (names == null) {
292 log.debug("Capture agent '{}' failed to provide device names ({})", name, CaptureParameters.CAPTURE_DEVICE_NAMES);
293 return;
294 }
295
296 capabilitiesProperties.put(CaptureParameters.CAPTURE_DEVICE_NAMES, names);
297
298 String[] friendlyNames = names.split(",");
299 HashMap<String, Integer> propertyCounts = new HashMap<String, Integer>();
300 for (String name : friendlyNames) {
301 propertyCounts.put(name, 0);
302 }
303
304
305 for (String key : configuration.stringPropertyNames()) {
306
307 for (String name : friendlyNames) {
308 String check = CaptureParameters.CAPTURE_DEVICE_PREFIX + name;
309
310 if (key.contains(check)) {
311 String property = configuration.getProperty(key);
312 if (property == null) {
313 log.error("Unable to expand variable in value for key {}, returning null!", key);
314 capabilitiesProperties = null;
315 return;
316 }
317 capabilitiesProperties.setProperty(key, property);
318 propertyCounts.put(name, propertyCounts.get(name) + 1);
319 }
320 }
321 }
322 }
323
324
325
326
327 @SuppressWarnings("unused")
328 @PostLoad
329 private void loadCaps() {
330 configurationProperties = new Properties();
331 if (configurationString == null) {
332 log.info("No configuration properties set yet for '{}'", name);
333 } else {
334 try {
335 configurationProperties.load(new StringReader(this.configurationString));
336 this.setConfiguration(configurationProperties);
337 } catch (IOException e) {
338 log.warn("Unable to load agent " + name + "'s capabilities, IO exception occurred.", e);
339 }
340 }
341 }
342
343
344
345
346
347
348 @Override
349 public boolean equals(Object o) {
350 if (this == o) {
351 return true;
352 }
353 if (o instanceof AgentImpl) {
354 return name.equals(((AgentImpl) o).name);
355 } else {
356 return false;
357 }
358 }
359
360
361
362
363
364
365 @Override
366 public int hashCode() {
367 return name.hashCode();
368 }
369 }