1 package com.trendmicro.grid.acl.ds.jpa;
2
3 import com.trendmicro.grid.acl.ds.ReportReceiver;
4 import com.trendmicro.grid.acl.ds.jpa.entities.JpaFileDetails;
5 import com.trendmicro.grid.acl.ds.jpa.entities.JpaFileReport;
6 import com.trendmicro.grid.acl.ds.jpa.util.FileQueryConfigurator;
7 import com.trendmicro.grid.acl.l0.datatypes.FileReport;
8 import net.sf.tinyjee.config.PropertySection;
9 import net.sf.tinyjee.util.Hex;
10 import org.slf4j.Logger;
11 import org.slf4j.LoggerFactory;
12 import org.springframework.stereotype.Repository;
13 import org.springframework.transaction.annotation.Transactional;
14
15 import javax.annotation.PostConstruct;
16 import javax.annotation.Resource;
17 import javax.persistence.EntityManager;
18 import javax.persistence.PersistenceContext;
19 import javax.persistence.Query;
20 import java.util.ArrayList;
21 import java.util.Collection;
22 import java.util.Iterator;
23
24 import static com.trendmicro.grid.acl.ds.config.DataSourcePropertySection.KEY_IGNORE_STATISTICS_RECORDING;
25 import static com.trendmicro.grid.acl.ds.config.DataSourcePropertySection.getPropertySection;
26 import static com.trendmicro.grid.acl.ds.jpa.AbstractReceivedResultsHandler.getValue;
27
28
29
30
31
32
33
34 @Repository
35 @Transactional(readOnly = false)
36 public class JpaReportReceiver implements ReportReceiver {
37
38 private static final Logger log = LoggerFactory.getLogger(JpaReportReceiver.class);
39
40 @PersistenceContext(unitName = "CoreDB")
41 EntityManager em;
42
43 @Resource
44 JpaFileRepository fileRepository;
45
46 boolean ignoreStatisticsRecording;
47
48 @PostConstruct
49 void configure() {
50 PropertySection section = getPropertySection();
51 ignoreStatisticsRecording = getValue(section, KEY_IGNORE_STATISTICS_RECORDING);
52 }
53
54 @Override
55 public void receiveFileReports(Collection<FileReport> fileReports) {
56 final boolean debug = log.isDebugEnabled();
57 final FileQueryConfigurator<Integer> queryConfigurator = fileRepository.getReferenceQueryConfigurator();
58 final Query updateQuery = em.createNamedQuery("FileReport.UpdateAccessCount");
59
60
61
62 final Collection<JpaFileDetails> contentReferences = new ArrayList<JpaFileDetails>(fileReports.size());
63 for (FileReport report : fileReports)
64 contentReferences.add(fileRepository.getReference(queryConfigurator, report));
65
66 final Iterator<JpaFileDetails> referenceIterator = contentReferences.iterator();
67 for (FileReport report : fileReports) {
68 boolean entrySkipped = false;
69 final byte[] sha1 = report.getSHA1Hash();
70 final JpaFileDetails fileDetails = referenceIterator.next();
71
72 if (fileDetails != null) {
73 final JpaFileReport jpaReport = new JpaFileReport(fileDetails, report);
74 int updateCount = updateQuery.setParameter("accessCount", jpaReport.getAccessCount()).
75 setParameter("reportId", jpaReport.getReportId()).executeUpdate();
76
77 if (updateCount == 0) {
78 if (debug)
79 log.debug("Creating a new report entry '{}' for file '{}'", jpaReport.getTimePeriod(), Hex.encode(sha1));
80
81 if (!ignoreStatisticsRecording) {
82 em.persist(jpaReport);
83 em.flush();
84 em.detach(jpaReport);
85 }
86
87 } else {
88 if (log.isTraceEnabled()) {
89 log.trace("Incremented the access count of the existing report entry '{}' for file '{}', by {}", new Object[]{
90 jpaReport.getTimePeriod(), Hex.encode(sha1), report.getAmount()});
91 }
92 }
93 } else
94 entrySkipped = true;
95
96 if (entrySkipped) {
97 if (debug)
98 log.debug("Omitting storage of report for unknown file '{}' as the MD5 hash is missing.", Hex.encode(sha1));
99 }
100 }
101 if (!ignoreStatisticsRecording)
102 em.flush();
103 }
104 }