1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.miloss.fgsms.services.ars.impl;
21
22 import java.io.ByteArrayInputStream;
23 import java.io.StringWriter;
24 import java.sql.Connection;
25 import java.sql.PreparedStatement;
26 import java.sql.ResultSet;
27 import java.sql.SQLException;
28 import java.util.GregorianCalendar;
29 import java.util.UUID;
30 import javax.annotation.Resource;
31 import javax.jws.WebMethod;
32 import javax.jws.WebParam;
33 import javax.jws.WebResult;
34 import javax.jws.WebService;
35 import javax.xml.bind.JAXBContext;
36 import javax.xml.bind.JAXBElement;
37 import javax.xml.bind.Unmarshaller;
38 import javax.xml.bind.annotation.XmlSeeAlso;
39 import javax.xml.datatype.DatatypeConfigurationException;
40 import javax.xml.datatype.DatatypeFactory;
41 import java.util.Calendar;
42 import javax.xml.stream.XMLInputFactory;
43 import javax.xml.stream.XMLStreamReader;
44 import javax.xml.ws.RequestWrapper;
45 import javax.xml.ws.ResponseWrapper;
46 import javax.xml.ws.WebServiceContext;
47 import org.miloss.fgsms.common.AuditLogger;
48 import org.miloss.fgsms.common.DBSettingsLoader;
49 import org.miloss.fgsms.common.Constants;
50 import org.miloss.fgsms.common.UserIdentityUtil;
51 import org.miloss.fgsms.common.Utility;
52 import org.miloss.fgsms.services.interfaces.automatedreportingservice.*;
53 import org.miloss.fgsms.services.interfaces.automatedreportingservice.AccessDeniedException;
54 import org.miloss.fgsms.services.interfaces.automatedreportingservice.ServiceUnavailableException;
55 import org.miloss.fgsms.services.interfaces.common.GetOperatingStatusRequestMessage;
56 import org.miloss.fgsms.services.interfaces.common.GetOperatingStatusResponseMessage;
57 import org.miloss.fgsms.services.interfaces.common.SecurityWrapper;
58 import org.miloss.fgsms.services.interfaces.faults.ServiceUnavailableFaultCodes;
59 import org.miloss.fgsms.services.interfaces.policyconfiguration.*;
60 import org.miloss.fgsms.services.interfaces.reportingservice.ExportRecordsEnum;
61 import org.apache.log4j.Level;
62 import org.miloss.fgsms.common.Logger;
63 ;
64 import org.miloss.fgsms.common.DBUtils;
65 import org.miloss.fgsms.plugins.reporting.ReportGeneratorPlugin;
66 import org.miloss.fgsms.services.interfaces.reportingservice.ReportTypeContainer;
67 import us.gov.ic.ism.v2.ClassificationType;
68
69
70
71
72
73
74
75
76
77 @WebService(name = "automatedReportingService", targetNamespace = "urn:org:miloss:fgsms:services:interfaces:automatedReportingService"
78
79 )
80 @XmlSeeAlso({
81 org.miloss.fgsms.services.interfaces.policyconfiguration.ObjectFactory.class,
82 us.gov.ic.ism.v2.ObjectFactory.class,
83 org.miloss.fgsms.services.interfaces.reportingservice.ObjectFactory.class,
84 org.miloss.fgsms.services.interfaces.common.ObjectFactory.class,
85 org.miloss.fgsms.services.interfaces.faults.ObjectFactory.class,
86 org.miloss.fgsms.services.interfaces.automatedreportingservice.ObjectFactory.class
87 })
88 public class AutomatedReportingServiceImpl implements AutomatedReportingService, org.miloss.fgsms.services.interfaces.automatedreportingservice.OpStatusService {
89
90 private static final String name = "fgsms.AutomatedReportingService";
91 private static DatatypeFactory df = null;
92 private static Calendar started = null;
93 final static Logger log = Logger.getLogger(name);
94 private static final String OK = "OK";
95
96 private static void validatePluginRegistered(String type) throws Exception {
97 Connection configurationDBConnection = Utility.getConfigurationDBConnection();
98 PreparedStatement cmd = null;
99 ResultSet rs = null;
100 try {
101 cmd = configurationDBConnection.prepareStatement("select * from plugins where classname=? and appliesto='REPORTING'");
102 cmd.setString(1, type);
103 ResultSet executeQuery = cmd.executeQuery();
104 if (executeQuery.next()) {
105
106 } else {
107 throw new IllegalArgumentException("Plugin '" + type + "' not registered");
108 }
109 } catch (Exception ex) {
110 log.log(Level.WARN, null, ex);
111 throw ex;
112 } finally {
113 DBUtils.safeClose(rs);
114 DBUtils.safeClose(cmd);
115 DBUtils.safeClose(configurationDBConnection);
116 }
117 }
118
119 public AutomatedReportingServiceImpl() throws DatatypeConfigurationException {
120
121 Init();
122 }
123
124
125
126
127
128
129 public AutomatedReportingServiceImpl(WebServiceContext w) throws DatatypeConfigurationException {
130 ctx = w;
131 Init();
132 }
133 @Resource
134 private WebServiceContext ctx;
135
136 private synchronized void Init() throws DatatypeConfigurationException {
137 if (df == null) {
138 df = DatatypeFactory.newInstance();
139 }
140 if (started == null) {
141 GregorianCalendar gcal = new GregorianCalendar();
142 gcal.setTimeInMillis(System.currentTimeMillis());
143 started = (gcal);
144 }
145 }
146
147
148
149
150
151
152
153
154
155
156
157 @WebMethod(operationName = "GetMyScheduledReports", action = "urn:org:miloss:fgsms:services:interfaces:automatedReportingService/GetMyScheduledReports")
158 @WebResult(name = "response", targetNamespace = "urn:org:miloss:fgsms:services:interfaces:automatedReportingService")
159 @RequestWrapper(localName = "GetMyScheduledReports", targetNamespace = "urn:org:miloss:fgsms:services:interfaces:automatedReportingService", className = "org.miloss.fgsms.services.interfaces.automatedreportingservice.GetMyScheduledReports")
160 @ResponseWrapper(localName = "GetMyScheduledReportsResponse", targetNamespace = "urn:org:miloss:fgsms:services:interfaces:automatedReportingService", className = "org.miloss.fgsms.services.interfaces.automatedreportingservice.GetMyScheduledReportsResponse")
161 public GetMyScheduledReportsResponseMsg getMyScheduledReports(
162 @WebParam(name = "request", targetNamespace = "urn:org:miloss:fgsms:services:interfaces:automatedReportingService") GetMyScheduledReportsRequestMsg request)
163 throws AccessDeniedException, ServiceUnavailableException {
164 String currentUser = UserIdentityUtil.getFirstIdentityToString(ctx);
165 if (request == null) {
166 AuditLogger.logItem(this.getClass().getCanonicalName(), "getMyScheduledReports", currentUser, "", "not specified", ctx.getMessageContext());
167 throw new IllegalArgumentException("request is null");
168 }
169 Utility.validateClassification(request.getClassification());
170
171 AuditLogger.logItem(this.getClass().getCanonicalName(), "getMyScheduledReports", currentUser, "", (request.getClassification()), ctx.getMessageContext());
172
173
174
175 if (request.getRecordlimit() == 0) {
176 request.setRecordlimit(100);
177 }
178
179 GetMyScheduledReportsResponseMsg ret = new GetMyScheduledReportsResponseMsg();
180 Connection con = null;
181 PreparedStatement cmd = null;
182 ResultSet rs = null;
183 try {
184 ret.setClassification(getCurrentOperatingClassificationLevel());
185 JAXBContext GetARSSerializationContext = Utility.getARSSerializationContext();
186 Unmarshaller u = GetARSSerializationContext.createUnmarshaller();
187 con = Utility.getPerformanceDBConnection();
188 cmd = con.prepareStatement("select * from arsjobs where owninguser=?;");
189 cmd.setString(1, currentUser);
190 rs = cmd.executeQuery();
191 while (rs.next()) {
192 ExistingReportDefitions ed = new ExistingReportDefitions();
193 byte[] s = rs.getBytes("reportdef");
194 ByteArrayInputStream bss = new ByteArrayInputStream(s);
195 XMLInputFactory xf = XMLInputFactory.newInstance();
196 XMLStreamReader r = xf.createXMLStreamReader(bss);
197 JAXBElement<ReportDefinition> foo = (JAXBElement<ReportDefinition>) u.unmarshal(r, ReportDefinition.class);
198 if (foo != null && foo.getValue() != null) {
199 ed.setJob(foo.getValue());
200 }
201 ed.getJob().setLastRanAt(ConvertToXmlGreg(rs.getLong("lastranat")));
202 ret.getCompletedJobs().add(ed);
203 }
204 } catch (Exception ex) {
205 log.log(Level.ERROR, null, ex);
206 } finally {
207 DBUtils.safeClose(rs);
208 DBUtils.safeClose(cmd);
209 DBUtils.safeClose(con);
210 }
211 con = null;
212
213 try {
214 con = Utility.getPerformanceDBConnection();
215
216
217 for (int i = 0; i < ret.getCompletedJobs().size(); i++) {
218
219 cmd = con.prepareStatement("select * from arsreports where jobid=? limit ? offset ?");
220 cmd.setString(1, ret.getCompletedJobs().get(i).getJob().getJobId());
221 cmd.setInt(2, request.getRecordlimit());
222 cmd.setInt(3, request.getOffset());
223 rs = cmd.executeQuery();
224 while (rs.next()) {
225 CompletedJobs cj = new CompletedJobs();
226 cj.setReportId(rs.getString("reportid"));
227 cj.setTimestamp(ConvertToXmlGreg(rs.getLong("datetime")));
228 ret.getCompletedJobs().get(i).getReports().add(cj);
229 }
230
231 rs.close();
232 cmd.close();
233 }
234 return ret;
235 } catch (Exception ex) {
236 log.log(Level.ERROR, null, ex);
237 } finally {
238 DBUtils.safeClose(rs);
239 DBUtils.safeClose(cmd);
240 DBUtils.safeClose(con);
241 }
242 ServiceUnavailableException f = new ServiceUnavailableException("", null);
243 f.getFaultInfo().setCode(ServiceUnavailableFaultCodes.DATA_BASE_UNAVAILABLE);
244 throw f;
245
246 }
247
248 private ReportDefinition loadReportDef(String job) throws Exception {
249 Connection con = null;
250 PreparedStatement cmd = null;
251 ResultSet rs = null;
252 try {
253 ReportDefinition ret = null;
254 JAXBContext GetARSSerializationContext = Utility.getARSSerializationContext();
255 Unmarshaller u = GetARSSerializationContext.createUnmarshaller();
256 con = Utility.getPerformanceDBConnection();
257 cmd = con.prepareStatement("select * from arsjobs where jobid=?;");
258 cmd.setString(1, job);
259 rs = cmd.executeQuery();
260 if (rs.next()) {
261
262 byte[] s = rs.getBytes("reportdef");
263 ByteArrayInputStream bss = new ByteArrayInputStream(s);
264 XMLInputFactory xf = XMLInputFactory.newInstance();
265 XMLStreamReader r = xf.createXMLStreamReader(bss);
266 JAXBElement<ReportDefinition> foo = (JAXBElement<ReportDefinition>) u.unmarshal(r, ReportDefinition.class);
267 if (foo != null && foo.getValue() != null) {
268 ret = foo.getValue();
269 }
270
271 }
272
273 return ret;
274 } catch (Exception ex) {
275 log.log(Level.WARN, "loadReportDef error", ex);
276 } finally {
277 DBUtils.safeClose(rs);
278 DBUtils.safeClose(cmd);
279 DBUtils.safeClose(con);
280 }
281 throw new IllegalArgumentException("job not found");
282 }
283
284 private SecurityWrapper getCurrentOperatingClassificationLevel() {
285 try {
286 SecurityWrapper t = getGlobalPolicyFromDB().getClassification();
287 log.log(Level.INFO, "PCS, current security classification is " + Utility.ICMClassificationToString(t.getClassification()) + " " + t.getCaveats());
288 return t;
289 } catch (Exception ex) {
290 log.log(Level.ERROR, "Unable to determine current classification level. Is the database available?", ex);
291 }
292 throw new IllegalAccessError();
293 }
294
295 private GetGlobalPolicyResponseMsg getGlobalPolicyFromDB() throws org.miloss.fgsms.services.interfaces.policyconfiguration.ServiceUnavailableException, ServiceUnavailableException {
296
297 Connection con = Utility.getConfigurationDBConnection();
298 PreparedStatement comm = null;
299 ResultSet results = null;
300 boolean foundPolicy = false;
301 GetGlobalPolicyResponseMsg response = new GetGlobalPolicyResponseMsg();
302 try {
303 response.setPolicy(new GlobalPolicy());
304
305
306 comm = con.prepareStatement("Select * from GlobalPolicies;");
307
308
309
310
311 results = comm.executeQuery();
312
313
314 if (results.next()) {
315 response.getPolicy().setPolicyRefreshRate(df.newDuration(results.getLong("PolicyRefreshRate")));
316 response.getPolicy().setRecordedMessageCap(results.getInt("RecordedMessageCap"));
317 SecurityWrapper wrap = new SecurityWrapper(ClassificationType.fromValue(results.getString("classification")),
318 results.getString("caveat"));
319 response.setClassification(wrap);
320 response.getPolicy().setAgentsEnabled(results.getBoolean("agentsenable"));
321 foundPolicy = true;
322 }
323 } catch (Exception ex) {
324 log.log(Level.ERROR, "error getting global policy", ex);
325 ServiceUnavailableException f = new ServiceUnavailableException("", null);
326 f.getFaultInfo().setCode(ServiceUnavailableFaultCodes.DATA_BASE_UNAVAILABLE);
327 throw f;
328 } finally {
329 DBUtils.safeClose(results);
330 DBUtils.safeClose(comm);
331 DBUtils.safeClose(con);
332 }
333
334 try {
335 if (!foundPolicy) {
336 try {
337 comm = con.prepareStatement("INSERT INTO GlobalPolicies (PolicyRefreshRate, RecordedMessageCap, classification, agentsenable, caveat) "
338 + " VALUES (?, ?, ?, true, ?);");
339 comm.setLong(1, 30 * 60 * 100);
340 comm.setLong(2, 1024000);
341 comm.setString(3, "U");
342 comm.setString(4, "");
343 comm.execute();
344 response.getPolicy().setRecordedMessageCap(1024000);
345 response.getPolicy().setClassification(new SecurityWrapper(ClassificationType.U, ""));
346 response.getPolicy().setAgentsEnabled(true);
347 } catch (SQLException ex) {
348 log.log(Level.ERROR, "error setting global policy", ex);
349 }
350 }
351 KeyNameValueEnc d = DBSettingsLoader.GetPropertiesFromDB(true, "UddiPublisher", "Interval");
352 if (d != null && d.getKeyNameValue() != null) {
353 try {
354 response.getPolicy().setUDDIPublishRate(df.newDuration(Long.parseLong(d.getKeyNameValue().getPropertyValue())));
355 } catch (Exception ex) {
356 response.getPolicy().setUDDIPublishRate(df.newDuration(30 * 60 * 100));
357 }
358 }
359
360 return response;
361 } catch (Exception ex) {
362 log.log(Level.ERROR, "error getting global policy", ex);
363 ServiceUnavailableException f = new ServiceUnavailableException("", null);
364 f.getFaultInfo().setCode(ServiceUnavailableFaultCodes.DATA_BASE_UNAVAILABLE);
365 throw f;
366 } finally {
367 DBUtils.safeClose(comm);
368 DBUtils.safeClose(con);
369 }
370
371 }
372
373
374
375
376
377
378
379
380
381 @WebMethod(operationName = "AddOrUpdateScheduledReport", action = "urn:org:miloss:fgsms:services:interfaces:automatedReportingService/AddOrUpdateScheduledReport")
382 @WebResult(name = "response", targetNamespace = "urn:org:miloss:fgsms:services:interfaces:automatedReportingService")
383 @RequestWrapper(localName = "AddOrUpdateScheduledReport", targetNamespace = "urn:org:miloss:fgsms:services:interfaces:automatedReportingService", className = "org.miloss.fgsms.services.interfaces.automatedreportingservice.AddOrUpdateScheduledReport")
384 @ResponseWrapper(localName = "AddOrUpdateScheduledReportResponse", targetNamespace = "urn:org:miloss:fgsms:services:interfaces:automatedReportingService", className = "org.miloss.fgsms.services.interfaces.automatedreportingservice.AddOrUpdateScheduledReportResponse")
385 public AddOrUpdateScheduledReportResponseMsg addOrUpdateScheduledReport(
386 @WebParam(name = "request", targetNamespace = "urn:org:miloss:fgsms:services:interfaces:automatedReportingService") AddOrUpdateScheduledReportRequestMsg request)
387 throws AccessDeniedException, ServiceUnavailableException {
388 String currentUser = UserIdentityUtil.getFirstIdentityToString(ctx);
389 if (request == null) {
390 AuditLogger.logItem(this.getClass().getCanonicalName(), "addOrUpdateScheduledReport", currentUser, "", "not specified", ctx.getMessageContext());
391 throw new IllegalArgumentException("request is null");
392 }
393 Utility.validateClassification(request.getClassification());
394 if (request.getJobs().isEmpty()) {
395 throw new IllegalArgumentException("at least one report must be specified for updating");
396 }
397 AuditLogger.logItem(this.getClass().getCanonicalName(), "addOrUpdateScheduledReport", currentUser, "", (request.getClassification()), ctx.getMessageContext());
398
399
400
401 validateRequest(request, currentUser, ctx);
402
403
404
405 Connection con = Utility.getPerformanceDBConnection();
406 for (int i = 0; i < request.getJobs().size(); i++) {
407 PreparedStatement cmd = null;
408 try {
409
410 StringWriter sw = new StringWriter();
411
412 if (!Utility.stringIsNullOrEmpty(request.getJobs().get(i).getJobId())) {
413 cmd = con.prepareStatement("UPDATE arsjobs SET reportdef=?, hasextrapermissions=?, enabled=? WHERE jobid=?;");
414
415 cmd.setBoolean(2, !request.getJobs().get(i).getAdditionalReaders().isEmpty());
416 cmd.setBoolean(3, request.getJobs().get(i).isEnabled());
417 cmd.setString(4, request.getJobs().get(i).getJobId());
418 } else {
419 request.getJobs().get(i).setJobId(UUID.randomUUID().toString());
420 cmd = con.prepareStatement("INSERT INTO arsjobs (reportdef, hasextrapermissions, enabled, lastranat, jobid, owninguser) values (?,?,?,?,?,?);");
421
422 cmd.setBoolean(2, !request.getJobs().get(i).getAdditionalReaders().isEmpty());
423
424 cmd.setBoolean(3, request.getJobs().get(i).isEnabled());
425 cmd.setLong(4, 0);
426 cmd.setString(5, request.getJobs().get(i).getJobId());
427 cmd.setString(6, currentUser);
428 }
429 Utility.getARSSerializationContext().createMarshaller().marshal(request.getJobs().get(i), sw);
430 byte[] bits = sw.toString().getBytes(Constants.CHARSET);
431 cmd.setBytes(1, bits);
432 cmd.executeUpdate();
433 cmd.close();
434 } catch (Exception ex) {
435 log.log(Level.ERROR, null, ex);
436 } finally {
437 DBUtils.safeClose(cmd);
438 }
439 }
440 if (con != null) {
441 DBUtils.safeClose(con);
442 }
443 AddOrUpdateScheduledReportResponseMsg r = new AddOrUpdateScheduledReportResponseMsg();
444 r.setClassification(getCurrentOperatingClassificationLevel());
445 r.getJobs().addAll(request.getJobs());
446 r.setSuccess(true);
447 r.setMessage(OK);
448 return r;
449
450 }
451
452
453
454
455
456
457
458
459
460
461 @WebMethod(operationName = "DeleteScheduledReport", action = "urn:org:miloss:fgsms:services:interfaces:automatedReportingService/DeleteScheduledReport")
462 @WebResult(name = "response", targetNamespace = "urn:org:miloss:fgsms:services:interfaces:automatedReportingService")
463 @RequestWrapper(localName = "DeleteScheduledReport", targetNamespace = "urn:org:miloss:fgsms:services:interfaces:automatedReportingService", className = "org.miloss.fgsms.services.interfaces.automatedreportingservice.DeleteScheduledReport")
464 @ResponseWrapper(localName = "DeleteScheduledReportResponse", targetNamespace = "urn:org:miloss:fgsms:services:interfaces:automatedReportingService", className = "org.miloss.fgsms.services.interfaces.automatedreportingservice.DeleteScheduledReportResponse")
465 public DeleteScheduledReportResponseMsg deleteScheduledReport(
466 @WebParam(name = "request", targetNamespace = "urn:org:miloss:fgsms:services:interfaces:automatedReportingService") DeleteScheduledReportRequestMsg request)
467 throws AccessDeniedException, ServiceUnavailableException {
468 String currentUser = UserIdentityUtil.getFirstIdentityToString(ctx);
469 if (request == null) {
470 AuditLogger.logItem(this.getClass().getCanonicalName(), "deleteScheduledReport", currentUser, "", "not specified", ctx.getMessageContext());
471 throw new IllegalArgumentException("request is null");
472 }
473 Utility.validateClassification(request.getClassification());
474
475 if (Utility.stringIsNullOrEmpty(request.getJobId())) {
476 throw new IllegalArgumentException("a job id must be specified");
477 }
478 AuditLogger.logItem(this.getClass().getCanonicalName(), "deleteScheduledReport", currentUser, request.getJobId(), (request.getClassification()), ctx.getMessageContext());
479
480 Connection con = null;
481 PreparedStatement cmd = null;
482 try {
483
484 con = Utility.getPerformanceDBConnection();
485
486 if (UserIdentityUtil.hasGlobalAdministratorRole(currentUser, "deleteScheduledReport", request.getClassification(), ctx)) {
487 cmd = con.prepareStatement("delete from arsjobs where jobid=? ");
488 cmd.setString(1, request.getJobId());
489 } else {
490 cmd = con.prepareStatement("delete from arsjobs where owninguser=? and jobid=? ");
491 cmd.setString(1, currentUser);
492 cmd.setString(2, request.getJobId());
493 }
494 int jobsdeleted = cmd.executeUpdate();
495 cmd.close();
496 if (jobsdeleted == 0) {
497 con.close();
498 throw new AccessDeniedException("either the job doesn't exist or you don't own it", new org.miloss.fgsms.services.interfaces.faults.AccessDeniedException());
499 }
500
501 cmd = con.prepareStatement("delete from arsreports where jobid=? ");
502 cmd.setString(1, request.getJobId());
503 cmd.executeUpdate();
504
505 DeleteScheduledReportResponseMsg r = new DeleteScheduledReportResponseMsg();
506 r.setClassification(getCurrentOperatingClassificationLevel());
507 r.setSuccess(true);
508 r.setMessage(OK);
509 return r;
510 } catch (SQLException ex) {
511 log.log(Level.ERROR, null, ex);
512
513 ServiceUnavailableException f = new ServiceUnavailableException("", null);
514
515 f.getFaultInfo().setCode(ServiceUnavailableFaultCodes.DATA_BASE_UNAVAILABLE);
516 throw f;
517 } finally {
518 DBUtils.safeClose(cmd);
519 DBUtils.safeClose(con);
520 }
521 }
522
523
524
525
526
527
528
529
530
531
532 @WebMethod(operationName = "GetReport", action = "urn:org:miloss:fgsms:services:interfaces:automatedReportingService/GetReport")
533 @WebResult(name = "response", targetNamespace = "urn:org:miloss:fgsms:services:interfaces:automatedReportingService")
534 @RequestWrapper(localName = "GetReport", targetNamespace = "urn:org:miloss:fgsms:services:interfaces:automatedReportingService", className = "org.miloss.fgsms.services.interfaces.automatedreportingservice.GetReport")
535 @ResponseWrapper(localName = "GetReportResponse", targetNamespace = "urn:org:miloss:fgsms:services:interfaces:automatedReportingService", className = "org.miloss.fgsms.services.interfaces.automatedreportingservice.GetReportResponse")
536 public GetReportResponseMsg getReport(
537 @WebParam(name = "request", targetNamespace = "urn:org:miloss:fgsms:services:interfaces:automatedReportingService") GetReportRequestMsg request)
538 throws AccessDeniedException, ServiceUnavailableException {
539 String currentUser = UserIdentityUtil.getFirstIdentityToString(ctx);
540 if (request == null) {
541 AuditLogger.logItem(this.getClass().getCanonicalName(), "getReport", currentUser, "", "not specified", ctx.getMessageContext());
542 throw new IllegalArgumentException("request is null");
543 }
544 Utility.validateClassification(request.getClassification());
545 if (Utility.stringIsNullOrEmpty(request.getReportId())) {
546 throw new IllegalArgumentException("a report id must be specified");
547 }
548 AuditLogger.logItem(this.getClass().getCanonicalName(), "getReport", currentUser, request.getReportId(), (request.getClassification()), ctx.getMessageContext());
549 GetReportResponseMsg r = new GetReportResponseMsg();
550 r.setClassification(getCurrentOperatingClassificationLevel());
551 r.setReportId(request.getReportId());
552 r.setZippedReport(get_a_Report(request.getReportId(), currentUser, request.getClassification()));
553 if (r.getZippedReport() == null) {
554 throw new IllegalArgumentException("report not found");
555 }
556 return r;
557 }
558
559 protected byte[] get_a_Report(final String id, final String currentUser, SecurityWrapper wrapper) throws AccessDeniedException {
560 String job = null;
561 boolean access = false;
562 Connection con = null;
563 ResultSet rs = null;
564 PreparedStatement cmd = null;
565 try {
566 con = Utility.getPerformanceDBConnection();
567 cmd = con.prepareStatement("select jobid from arsreports where reportid=?");
568 cmd.setString(1, id);
569 rs = cmd.executeQuery();
570 if (rs.next()) {
571 job = rs.getString(1);
572 }
573 } catch (Exception ex) {
574 log.log(Level.ERROR, null, ex);
575 if (ex instanceof AccessDeniedException) {
576 throw (AccessDeniedException) ex;
577 }
578 } finally {
579 DBUtils.safeClose(rs);
580 DBUtils.safeClose(cmd);
581 DBUtils.safeClose(con);
582 }
583 try {
584
585 if (!Utility.stringIsNullOrEmpty(job)) {
586 ReportDefinition rd = loadReportDef(job);
587 if (rd.getOwner().equalsIgnoreCase(currentUser)) {
588 access = true;
589 } else {
590 for (int i = 0; i < rd.getAdditionalReaders().size(); i++) {
591 if (currentUser.equalsIgnoreCase(rd.getAdditionalReaders().get(i))) {
592 access = true;
593 }
594 }
595 }
596 if (access) {
597
598 con = Utility.getPerformanceDBConnection();
599 cmd = con.prepareStatement("select reportcontents from arsreports where reportid=?");
600 cmd.setString(1, id);
601 rs = cmd.executeQuery();
602 byte[] bits = null;
603 if (rs.next()) {
604 bits = rs.getBytes(1);
605 }
606 if (bits != null) {
607 return bits;
608 }
609 } else {
610 throw new AccessDeniedException("", new org.miloss.fgsms.services.interfaces.faults.AccessDeniedException());
611 }
612 } else {
613
614 return null;
615 }
616 } catch (Exception ex) {
617
618 if (ex instanceof AccessDeniedException) {
619 AuditLogger.logItem(this.getClass().getCanonicalName(), "getReport", currentUser, "FAILURE, attempt to access ARS report " + id, wrapper, ctx.getMessageContext());
620 throw (AccessDeniedException) ex;
621 }
622 log.log(Level.ERROR, null, ex);
623 } finally {
624 DBUtils.safeClose(rs);
625 DBUtils.safeClose(cmd);
626 DBUtils.safeClose(con);
627 }
628 return null;
629 }
630
631
632
633
634
635
636
637
638
639
640 @WebMethod(operationName = "DeleteReport", action = "urn:org:miloss:fgsms:services:interfaces:automatedReportingService/DeleteReport")
641 @WebResult(name = "response", targetNamespace = "urn:org:miloss:fgsms:services:interfaces:automatedReportingService")
642 @RequestWrapper(localName = "DeleteReport", targetNamespace = "urn:org:miloss:fgsms:services:interfaces:automatedReportingService", className = "org.miloss.fgsms.services.interfaces.automatedreportingservice.DeleteReport")
643 @ResponseWrapper(localName = "DeleteReportResponse", targetNamespace = "urn:org:miloss:fgsms:services:interfaces:automatedReportingService", className = "org.miloss.fgsms.services.interfaces.automatedreportingservice.DeleteReportResponse")
644 public DeleteReportResponseMsg deleteReport(
645 @WebParam(name = "request", targetNamespace = "urn:org:miloss:fgsms:services:interfaces:automatedReportingService") DeleteReportRequestMsg request)
646 throws AccessDeniedException, ServiceUnavailableException {
647 String currentUser = UserIdentityUtil.getFirstIdentityToString(ctx);
648 if (request == null) {
649 AuditLogger.logItem(this.getClass().getCanonicalName(), "deleteReport", currentUser, "", "not specified", ctx.getMessageContext());
650 throw new IllegalArgumentException("request is null");
651 }
652 Utility.validateClassification(request.getClassification());
653
654 if (Utility.stringIsNullOrEmpty(request.getReportId())) {
655 throw new IllegalArgumentException("a report id must be specified");
656 }
657 AuditLogger.logItem(this.getClass().getCanonicalName(), "deleteReport", currentUser, request.getReportId(), (request.getClassification()), ctx.getMessageContext());
658 boolean proceed = false;
659 Connection con = null;
660 PreparedStatement cmd = null;
661 ResultSet rs = null;
662 try {
663 con = Utility.getPerformanceDBConnection();
664 cmd = con.prepareStatement("select owninguser from arsjobs, arsreports where arsjobs.jobid=arsreports.jobid and arsreports.reportid=?;");
665 cmd.setString(1, request.getReportId());
666 rs = cmd.executeQuery();
667 if (rs.next()) {
668 String owner = rs.getString(1);
669 if (!Utility.stringIsNullOrEmpty(owner)) {
670 if (currentUser.equalsIgnoreCase(owner)) {
671 proceed = true;
672 }
673 }
674 }
675
676 } catch (Exception ex) {
677
678 log.log(Level.ERROR, "error getting global policy", ex);
679 ServiceUnavailableException f = new ServiceUnavailableException("", null);
680 f.getFaultInfo().setCode(ServiceUnavailableFaultCodes.DATA_BASE_UNAVAILABLE);
681 throw f;
682 } finally {
683 DBUtils.safeClose(rs);
684 DBUtils.safeClose(cmd);
685 DBUtils.safeClose(con);
686 }
687
688 if (proceed) {
689 try {
690 con = Utility.getPerformanceDBConnection();
691 cmd = con.prepareStatement("delete from arsreports where arsreports.reportid=?;");
692 cmd.setString(1, request.getReportId());
693 int k = cmd.executeUpdate();
694
695 if (k != 1) {
696 ServiceUnavailableException f = new ServiceUnavailableException("Deletion failed", null);
697 f.getFaultInfo().setCode(ServiceUnavailableFaultCodes.UNEXPECTED_ERROR);
698 throw f;
699 }
700 DeleteReportResponseMsg ret = new DeleteReportResponseMsg();
701 ret.setSuccess(true);
702 ret.setMessage(OK);
703 ret.setClassification(getCurrentOperatingClassificationLevel());
704 return ret;
705 } catch (Exception ex) {
706
707 log.log(Level.ERROR, "error removing reporting", ex);
708 ServiceUnavailableException f = new ServiceUnavailableException("", null);
709 f.getFaultInfo().setCode(ServiceUnavailableFaultCodes.DATA_BASE_UNAVAILABLE);
710 throw f;
711 } finally {
712 DBUtils.safeClose(rs);
713 DBUtils.safeClose(cmd);
714 DBUtils.safeClose(con);
715
716 }
717 } else
718 {
719 log.log(Level.ERROR, "cannot remove report, either the job or report doesn't exist or the current user doesn't own it " + currentUser);
720 AccessDeniedException f = new AccessDeniedException("", null);
721 throw f;
722 }
723 }
724
725 private Calendar ConvertToXmlGreg(long aLong) {
726 if (aLong == 0) {
727 return null;
728 }
729 GregorianCalendar gcal = new GregorianCalendar();
730 gcal.setTimeInMillis(aLong);
731 return (gcal);
732 }
733
734 private static boolean IsReportJobOwner(String currentUser, String jobId) {
735 Connection con = null;
736 boolean ok = false;
737 PreparedStatement cmd = null;
738 ResultSet rs = null;
739 try {
740 con = Utility.getPerformanceDBConnection();
741 cmd = con.prepareStatement("select * from arsjobs where jobid=? and owninguser=?");
742 cmd.setString(1, jobId);
743 cmd.setString(2, currentUser);
744 rs = cmd.executeQuery();
745 if (rs.next()) {
746 ok = true;
747 }
748
749 } catch (Exception ex) {
750 log.log(Level.ERROR, "error caught searching for a report job", ex);
751 } finally {
752 DBUtils.safeClose(rs);
753 DBUtils.safeClose(cmd);
754 DBUtils.safeClose(con);
755 }
756 return ok;
757 }
758
759 private static void assertNotNull(Object exportType) {
760 if (exportType == null) {
761 throw new IllegalArgumentException("a required value is null");
762 }
763 }
764
765 private static void assertFalse(boolean empty) {
766 if (empty) {
767 throw new IllegalArgumentException("The array is empty");
768 }
769 }
770
771 private static void validateRange(TimeRangeDiff range) {
772 if (range == null) {
773 throw new IllegalArgumentException("The time range diff is empty");
774 }
775 if (range.getStart() == null) {
776 throw new IllegalArgumentException("The time range diff start is empty");
777 }
778 if (range.getEnd() == null) {
779 throw new IllegalArgumentException("The time range diff endis empty");
780 }
781 if (range.getStart().equals(range.getEnd()) || range.getStart().isShorterThan(range.getEnd())) {
782 throw new IllegalArgumentException("The time range diff is invalid, start should be a longer duration that end");
783 }
784 }
785
786 private static void validReportDefinition(ReportDefinition get) {
787 if (get == null) {
788 throw new IllegalArgumentException("The report def is empty");
789 }
790 if (get.getSchedule() == null) {
791 throw new IllegalArgumentException("The schedule is empty");
792 }
793 if (get.getSchedule().getTriggers().isEmpty()) {
794 throw new IllegalArgumentException("The report def has no triggers defined.");
795 }
796
797 for (int i = 0; i < get.getSchedule().getTriggers().size(); i++) {
798 if (get.getSchedule().getTriggers().get(i).getStartingAt() == null) {
799 throw new IllegalArgumentException("The report def has invalid triggers.");
800 }
801
802 if (get.getSchedule().getTriggers().get(i) instanceof DailySchedule) {
803 DailySchedule ds = (DailySchedule) get.getSchedule().getTriggers().get(i);
804 if (ds.getReoccurs() == null || ds.getReoccurs().intValue() < 1) {
805 throw new IllegalArgumentException("The report def has invalid value for reoccuring.");
806 }
807 } else if (get.getSchedule().getTriggers().get(i) instanceof WeeklySchedule) {
808 WeeklySchedule ds = (WeeklySchedule) get.getSchedule().getTriggers().get(i);
809 if (ds.getDayOfTheWeekIs().isEmpty()) {
810 throw new IllegalArgumentException("The report def has invalid weekly schedule for day of the weeks.");
811 }
812 if (ds.getReoccurs() == null || ds.getReoccurs().intValue() < 1) {
813 throw new IllegalArgumentException("The report def has invalid value for reoccuring.");
814 }
815 } else if (get.getSchedule().getTriggers().get(i) instanceof MonthlySchedule) {
816 MonthlySchedule ds = (MonthlySchedule) get.getSchedule().getTriggers().get(i);
817 if (ds.getDayOfTheMonthIs().isEmpty()) {
818 throw new IllegalArgumentException("The report def has invalid weekly schedule for day of the month.");
819 }
820 if (ds.getMonthNameIs().isEmpty()) {
821 throw new IllegalArgumentException("The report def has invalid weekly schedule for month.");
822 }
823 } else if (get.getSchedule().getTriggers().get(i) instanceof OneTimeSchedule) {
824
825 } else if (get.getSchedule().getTriggers().get(i) instanceof ImmediateSchedule) {
826
827 } else {
828 throw new IllegalArgumentException("The report def has a trigger that is not intrepretable.");
829 }
830 }
831
832 if (get.getExportCSVDataRequestMsg() != null) {
833 Utility.validateClassification(get.getExportCSVDataRequestMsg().getClassification());
834 }
835 if (get.getExportDataRequestMsg() != null) {
836 Utility.validateClassification(get.getExportDataRequestMsg().getClassification());
837 }
838 }
839
840 private static void validateRequest(AddOrUpdateScheduledReportRequestMsg request, String currentUser, WebServiceContext ctx) throws AccessDeniedException {
841 for (int i = 0; i < request.getJobs().size(); i++) {
842 request.getJobs().get(i).setOwner(currentUser);
843 if (Utility.stringIsNullOrEmpty(request.getJobs().get(i).getJobId())) {
844
845
846 } else {
847
848
849 if (!IsReportJobOwner(currentUser, request.getJobs().get(i).getJobId())) {
850 AccessDeniedException f = new AccessDeniedException("the report job " + request.getJobs().get(i).getJobId() + " is not owned by you", null);
851 throw f;
852 }
853 }
854 if (request.getJobs().get(i).getExportCSVDataRequestMsg() == null && request.getJobs().get(i).getExportDataRequestMsg() == null) {
855 throw new IllegalArgumentException("one of ExportData or ExportCSV must be specified");
856 }
857 if (request.getJobs().get(i).getExportCSVDataRequestMsg() != null && request.getJobs().get(i).getExportDataRequestMsg() != null) {
858 throw new IllegalArgumentException("both ExportData and ExportCSV cannot be specified on the same report definition");
859 }
860
861 validReportDefinition(request.getJobs().get(i));
862 validateReportAlerts(request.getJobs().get(i));
863 if (request.getJobs().get(i).getExportCSVDataRequestMsg() != null) {
864 if (request.getJobs().get(i).getExportCSVDataRequestMsg().getExportType() != ExportRecordsEnum.AUDIT_LOGS
865 && request.getJobs().get(i).getExportCSVDataRequestMsg().getURLs().isEmpty()) {
866 throw new IllegalArgumentException("ExportCSV requires at least one URL when not requesting audit logs");
867 }
868 for (int k = 0; k < request.getJobs().get(i).getExportCSVDataRequestMsg().getURLs().size(); k++) {
869 if (request.getJobs().get(i).getExportCSVDataRequestMsg().getExportType() == ExportRecordsEnum.TRANSACTIONS) {
870 UserIdentityUtil.assertAuditAccess(request.getJobs().get(i).getExportCSVDataRequestMsg().getURLs().get(k), currentUser, "addOrUpdateScheduledReport", request.getClassification(), ctx);
871 } else {
872 UserIdentityUtil.assertReadAccess(request.getJobs().get(i).getExportCSVDataRequestMsg().getURLs().get(k), currentUser, "addOrUpdateScheduledReport", request.getClassification(), ctx);
873 }
874 }
875 assertNotNull(request.getJobs().get(i).getExportCSVDataRequestMsg().getExportType());
876 assertNotNull(request.getJobs().get(i).getExportCSVDataRequestMsg().getRange());
877 assertNotNull(request.getJobs().get(i).getExportCSVDataRequestMsg().getRange().getEnd());
878 assertNotNull(request.getJobs().get(i).getExportCSVDataRequestMsg().getRange().getStart());
879 validateRange(request.getJobs().get(i).getExportCSVDataRequestMsg().getRange());
880 if (request.getJobs().get(i).getExportCSVDataRequestMsg().getExportType() == ExportRecordsEnum.AUDIT_LOGS) {
881 UserIdentityUtil.assertGlobalAuditRole(currentUser, "ValidReportDefinition", request.getClassification(), ctx);
882 }
883 }
884 if (request.getJobs().get(i).getExportDataRequestMsg() != null) {
885 for (int k = 0; k < request.getJobs().get(i).getExportDataRequestMsg().getURLs().size(); k++) {
886 UserIdentityUtil.assertReadAccess(request.getJobs().get(i).getExportDataRequestMsg().getURLs().get(k), currentUser, "addOrUpdateScheduledReport", request.getClassification(), ctx);
887 }
888
889 assertNotNull(request.getJobs().get(i).getExportDataRequestMsg().getReportTypes());
890 assertNotNull(request.getJobs().get(i).getExportDataRequestMsg().getReportTypes().getReportTypeContainer());
891 assertFalse(request.getJobs().get(i).getExportDataRequestMsg().getReportTypes().getReportTypeContainer().isEmpty());
892
893 for (int k = 0; k < request.getJobs().get(i).getExportDataRequestMsg().getReportTypes().getReportTypeContainer().size(); k++) {
894 ReportTypeContainer reportType = request.getJobs().get(i).getExportDataRequestMsg().getReportTypes().getReportTypeContainer().get(i);
895 try {
896
897 validatePluginRegistered(reportType.getType());
898 } catch (Exception ex) {
899 log.warn(null, ex);
900 throw new IllegalArgumentException(ex.getMessage());
901 }
902
903 try {
904 ReportGeneratorPlugin plugin = (ReportGeneratorPlugin) Class.forName(reportType.getType()).newInstance();
905 } catch (Throwable t) {
906 log.warn(null, t);
907 throw new IllegalArgumentException(reportType.getType() + " could not be initialized");
908 }
909 }
910 assertNotNull(request.getJobs().get(i).getExportDataRequestMsg().getRange());
911 assertNotNull(request.getJobs().get(i).getExportDataRequestMsg().getRange().getEnd());
912 assertNotNull(request.getJobs().get(i).getExportDataRequestMsg().getRange().getStart());
913 validateRange(request.getJobs().get(i).getExportDataRequestMsg().getRange());
914
915 }
916 }
917 }
918
919 private static void validateReportAlerts(ReportDefinition get) {
920 if (get.getNotifications().isEmpty()) {
921 return;
922 }
923
924
925
926
927
928
929
930
931
932
933
934 }
935
936
937
938
939
940
941
942
943 @WebMethod(operationName = "GetOperatingStatus", action = "urn:org:miloss:fgsms:services:interfaces:opStatusService/GetOperatingStatus")
944 @WebResult(name = "response", targetNamespace = "urn:org:miloss:fgsms:services:interfaces:common")
945 @RequestWrapper(localName = "GetOperatingStatus", targetNamespace = "urn:org:miloss:fgsms:services:interfaces:common", className = "org.miloss.fgsms.services.interfaces.common.GetOperatingStatus")
946 @ResponseWrapper(localName = "GetOperatingStatusResponse", targetNamespace = "urn:org:miloss:fgsms:services:interfaces:common", className = "org.miloss.fgsms.services.interfaces.common.GetOperatingStatusResponse")
947 public GetOperatingStatusResponseMessage getOperatingStatus(
948 @WebParam(name = "request", targetNamespace = "urn:org:miloss:fgsms:services:interfaces:common") GetOperatingStatusRequestMessage request) {
949 String currentUser = UserIdentityUtil.getFirstIdentityToString(ctx);
950
951 Utility.validateClassification(request.getClassification());
952 AuditLogger.logItem(this.getClass().getCanonicalName(), "getOperatingStatus", currentUser, "", (request.getClassification()), ctx.getMessageContext());
953
954 GetOperatingStatusResponseMessage res = new GetOperatingStatusResponseMessage();
955
956 res.setClassification(request.getClassification());
957 res.setVersionInfo(new GetOperatingStatusResponseMessage.VersionInfo());
958 res.getVersionInfo().setVersionData(org.miloss.fgsms.common.Constants.Version);
959 res.getVersionInfo().setVersionSource(org.miloss.fgsms.common.Constants.class.getCanonicalName());
960 res.setStartedAt(started);
961 boolean ok = true;
962 Connection con = Utility.getConfigurationDBConnection();
963 Connection con2 = Utility.getPerformanceDBConnection();
964 PreparedStatement prepareStatement = null;
965 PreparedStatement prepareStatement2 = null;
966 try {
967 prepareStatement = con.prepareStatement("select 1=1;");
968 prepareStatement.execute();
969 prepareStatement.close();
970
971 prepareStatement2 = con2.prepareStatement("select 1=1;");
972 prepareStatement2.execute();
973 prepareStatement2.close();
974 res.setStatusMessage("OK");
975 } catch (Exception ex) {
976 log.log(Level.WARN, null, ex);
977 ok = false;
978 res.setStatusMessage("One or more of the database connections is available");
979 } finally {
980 DBUtils.safeClose(prepareStatement);
981 DBUtils.safeClose(prepareStatement2);
982
983 DBUtils.safeClose(con2);
984 DBUtils.safeClose(con);
985 }
986 res.setStatus(ok);
987 return res;
988 }
989 }