Project

General

Profile

1
package eu.dnetlib.msro.logging;
2

    
3
import java.time.LocalDateTime;
4
import java.time.ZoneId;
5
import java.util.HashMap;
6
import java.util.Iterator;
7
import java.util.Map;
8
import java.util.Map.Entry;
9
import java.util.stream.Collectors;
10

    
11
import org.apache.commons.lang3.StringUtils;
12
import org.apache.commons.logging.Log;
13
import org.apache.commons.logging.LogFactory;
14
import org.bson.Document;
15
import org.bson.conversions.Bson;
16
import org.springframework.beans.factory.annotation.Required;
17

    
18
import com.mongodb.BasicDBObject;
19
import com.mongodb.BasicDBObjectBuilder;
20
import com.mongodb.DBObject;
21
import com.mongodb.client.MongoCollection;
22
import com.mongodb.client.MongoCursor;
23
import com.mongodb.client.MongoDatabase;
24
import com.mongodb.client.model.Filters;
25

    
26
public class DnetLoggerMongoDao implements DnetLoggerDao {
27

    
28
	private static final Log log = LogFactory.getLog(DnetLoggerMongoDao.class);
29

    
30
	private MongoDatabase db;
31

    
32
	@Override
33
	public void init(final String collection) {
34
		final MongoCollection<Document> coll = db.getCollection(collection);
35
		if (coll == null) {
36
			log.info(String.format("creating collection %s", collection));
37
			db.createCollection(collection);
38
		}
39
	}
40

    
41
	@Override
42
	public void configureIndex(final String collection, final Map<String, IndexConf> conf) {
43
		final MongoCollection<DBObject> coll = db.getCollection(collection, DBObject.class);
44
		coll.dropIndexes();
45
		for (final String key : conf.keySet()) {
46
			coll.createIndex(new BasicDBObject(key, 1));
47
		}
48
	}
49

    
50
	@Override
51
	public void writeLog(final String collection, final Map<String, Object> map) {
52
		final MongoCollection<DBObject> coll = db.getCollection(collection, DBObject.class);
53
		final DBObject obj = BasicDBObjectBuilder.start(replaceKeyNames(map)).get();
54
		coll.insertOne(obj);
55
	}
56

    
57
	private Map<String, Object> replaceKeyNames(final Map<String, Object> inputMap) {
58
		final Map<String, Object> outMap = new HashMap<>();
59

    
60
		if (inputMap != null) {
61
			for (final Entry<String, Object> e : inputMap.entrySet()) {
62
				final String k = e.getKey();
63
				if (StringUtils.isNotBlank(k)) {
64
					final Object v = e.getValue();
65
					outMap.put(k.replaceAll("\\.", "_"), v != null ? v : "null");
66
				}
67
			}
68
		}
69
		return outMap;
70
	}
71

    
72
	@Override
73
	public Map<String, String> findOne(final String collection, final String key, final String value) {
74
		final MongoCollection<DBObject> coll = db.getCollection(collection, DBObject.class);
75
		final DBObject obj = coll.find(Filters.eq(key, value)).sort(new BasicDBObject(LogMessage.LOG_DATE_FIELD, -1)).first();
76
		return dbObject2Map(obj);
77
	}
78

    
79
	@Override
80
	public Map<String, String> findOne(final String collection, final Map<String, Object> criteria) {
81
		final MongoCollection<DBObject> coll = db.getCollection(collection, DBObject.class);
82
		final DBObject obj = coll.find(new BasicDBObject(criteria)).sort(new BasicDBObject(LogMessage.LOG_DATE_FIELD, -1)).first();
83
		return dbObject2Map(obj);
84
	}
85

    
86
	@Override
87
	public Iterator<Map<String, String>> obtainLogIterator(final String collection) {
88
		final MongoCollection<DBObject> coll = db.getCollection(collection, DBObject.class);
89
		return iter(collection, coll.find().iterator());
90
	}
91

    
92
	@Override
93
	public Iterator<Map<String, String>> find(final String collection, final String key, final String value) {
94
		final MongoCollection<DBObject> coll = db.getCollection(collection, DBObject.class);
95
		return iter(collection, coll.find(Filters.eq(key, value)).iterator());
96
	}
97

    
98
	@Override
99
	public Iterator<Map<String, String>> find(final String collection, final Map<String, Object> criteria) {
100
		final MongoCollection<DBObject> coll = db.getCollection(collection, DBObject.class);
101
		return iter(collection, coll.find(new BasicDBObject(criteria)).iterator());
102
	}
103

    
104
	@Override
105
	public Iterator<Map<String, String>> findByDateRange(final String collection, final LocalDateTime startDate, final LocalDateTime endDate) {
106
		final MongoCollection<DBObject> coll = db.getCollection(collection, DBObject.class);
107
		final Bson dateQuery = dateRangeQuery(startDate, endDate);
108
		// System.out.println(mongoQueryObject);
109
		return iter(collection, coll.find(dateQuery).iterator());
110
	}
111

    
112
	@Override
113
	public Iterator<Map<String, String>> findByDateRange(final String collection,
114
			final LocalDateTime startDate,
115
			final LocalDateTime endDate,
116
			final String key,
117
			final String value) {
118
		final MongoCollection<DBObject> coll = db.getCollection(collection, DBObject.class);
119
		final Bson dateQuery = dateRangeQuery(startDate, endDate);
120
		final BasicDBObject customQuery = new BasicDBObject(key, value);
121

    
122
		return iter(collection, coll.find(Filters.and(dateQuery, customQuery)).iterator());
123
	}
124

    
125
	@Override
126
	public Iterator<Map<String, String>> findByDateRange(final String collection,
127
			final LocalDateTime startDate,
128
			final LocalDateTime endDate,
129
			final Map<String, Object> criteria) {
130
		final MongoCollection<DBObject> coll = db.getCollection(collection, DBObject.class);
131
		final Bson dateQuery = dateRangeQuery(startDate, endDate);
132
		final BasicDBObject customQuery = new BasicDBObject(criteria);
133

    
134
		return iter(collection, coll.find(Filters.and(dateQuery, customQuery)).iterator());
135
	}
136

    
137
	private Bson dateRangeQuery(final LocalDateTime startDate, final LocalDateTime endDate) {
138

    
139
		final long start = startDate.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
140
		final long end = endDate.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
141

    
142
		final Bson dateFilter =
143
				Filters.and(Filters.gte(LogMessage.LOG_DATE_FIELD, start), Filters.lt(LogMessage.LOG_DATE_FIELD, end));
144
		log.debug("Date filter created: " + dateFilter);
145
		// return new BasicDBObject(LogMessage.LOG_DATE_FIELD, BasicDBObjectBuilder.start("$gte", startDate.getTime()).append("$lt",
146
		// endDate.getTime()).get());
147
		return dateFilter;
148
	}
149

    
150
	private Iterator<Map<String, String>> iter(final String collection, final MongoCursor<DBObject> cursor) {
151
		return new Iterator<Map<String, String>>() {
152

    
153
			@Override
154
			public boolean hasNext() {
155
				return cursor.hasNext();
156
			}
157

    
158
			@Override
159
			public Map<String, String> next() {
160
				return dbObject2Map(cursor.next());
161
			}
162

    
163
			@Override
164
			public void remove() {
165
				throw new RuntimeException("NOT IMPLEMENTED");
166
			}
167
		};
168
	}
169

    
170
	public MongoDatabase getDb() {
171
		return db;
172
	}
173

    
174
	@Required
175
	public void setDb(final MongoDatabase db) {
176
		this.db = db;
177
	}
178

    
179
	private Map<String, String> dbObject2Map(final DBObject obj) {
180
		return obj != null ? obj.keySet()
181
				.stream()
182
				.filter(k -> !k.startsWith("_"))
183
				.collect(Collectors.toMap(k -> k, k -> "" + obj.get(k))) : new HashMap<>();
184

    
185
	}
186

    
187
}
(5-5/7)