Project

General

Profile

1
package eu.dnetlib.pid.resolver.store;
2

    
3
import com.mongodb.*;
4
import com.mongodb.client.FindIterable;
5
import com.mongodb.client.MongoCollection;
6
import com.mongodb.client.MongoCursor;
7
import com.mongodb.client.MongoDatabase;
8
import com.mongodb.client.model.UpdateOptions;
9
import eu.dnetlib.enabling.tools.DnetStreamSupport;
10
import eu.dnetlib.miscutils.functional.xml.DnetXsltFunctions;
11
import eu.dnetlib.pid.resolver.model.ResolvedObject;
12
import eu.dnetlib.pid.resolver.model.factory.ResolvedObjectFactory;
13
import org.apache.commons.lang3.StringUtils;
14
import org.apache.commons.logging.Log;
15
import org.apache.commons.logging.LogFactory;
16
import org.bson.Document;
17
import org.bson.conversions.Bson;
18
import org.springframework.beans.factory.annotation.Autowired;
19
import org.springframework.beans.factory.annotation.Required;
20
import org.springframework.beans.factory.annotation.Value;
21

    
22
import java.util.ArrayList;
23
import java.util.Arrays;
24
import java.util.List;
25
import java.util.stream.Collectors;
26
import java.util.stream.StreamSupport;
27

    
28
/**
29
 * Created by sandro on 9/7/16.
30
 */
31
public class ResolverStore {
32

    
33
	private static final Log log = LogFactory.getLog(ResolverStore.class);
34

    
35
	@Value("${services.pid.resolver.header}")
36
	private String ns_header;
37

    
38
	private static List<String> requirededIndex = new ArrayList<>(Arrays.asList(
39
			"pid",
40
			"pid_type",
41
			"resolver",
42
			"dnet_identifier",
43
			"typology"
44
	));
45
	private final UpdateOptions upsert = new UpdateOptions().upsert(true);
46

    
47
	private MongoClient mongoClient;
48

    
49
	private MongoDatabase mongoDatabase;
50

    
51
	private MongoCollection<DBObject> resolverCollection;
52

    
53
	private String collectionName;
54

    
55
	private String databaseName;
56

    
57
	@Autowired
58
	private ResolvedObjectFactory objectFactory;
59

    
60

    
61
	public void checkIntegrityCollection() {
62
		getMongoDatabase().getCollection(collectionName);
63
		final MongoCollection<DBObject> collection = getMongoDatabase().getCollection(collectionName, DBObject.class);
64
		List<String> idxName = StreamSupport.stream(collection.listIndexes().spliterator(), false)
65
				.map(document -> ((Document) document.get("key")).keySet().iterator().next())
66
				.collect(Collectors.toList());
67

    
68
		final List<String> toAdd = requirededIndex.stream()
69
				.filter(it -> !idxName.contains(it))
70
				.collect(Collectors.toList());
71

    
72
		for (String idx : toAdd) {
73
			log.debug("Adding " + idx + " index");
74
			collection.createIndex(new Document(idx, 1));
75
		}
76
		this.resolverCollection = collection;
77
	}
78

    
79
	public List<String> getIndexName() {
80
		return StreamSupport.stream(this.resolverCollection.listIndexes().spliterator(), false)
81
				.map(document -> ((Document) document.get("key")).keySet().iterator().next())
82
				.collect(Collectors.toList());
83
	}
84

    
85
	public void insertRecord(final String resolver, final ResolvedObject resolvedObject) {
86
		if (this.resolverCollection == null) {
87
			checkIntegrityCollection();
88
		}
89
		final DBObject currentObject = BasicDBObjectBuilder.start()
90
                .add("pid", resolvedObject.getPid().toLowerCase())
91
                .add("pid_type", resolvedObject.getPidType().toLowerCase())
92
                .add("dnet_identifier", generateDNetIdentifier(resolvedObject))
93
				.add("resolver", resolver)
94
				.add("typology", resolvedObject.getType().toString())
95
				.add("body", resolvedObject.toJsonString())
96
				.get();
97
		final Bson dnet_identifier = (Bson) BasicDBObjectBuilder.start().add("dnet_identifier", ns_header + resolvedObject.getIdentifier()).get();
98
		this.resolverCollection.replaceOne(dnet_identifier, currentObject, upsert);
99
	}
100

    
101
	public String generateDNetIdentifier(final String pid, final String pidType) {
102
		if (StringUtils.isBlank(pid) || StringUtils.isBlank(pidType))
103
			throw new RuntimeException("Error pid or pidtype cannot be null");
104
		return ns_header + DnetXsltFunctions.md5(String.format("%s::%s", pid.trim().toLowerCase(), pidType.toLowerCase().trim()));
105
	}
106

    
107
	public String generateDNetIdentifier(final ResolvedObject object) {
108
		return ns_header + object.getIdentifier();
109
	}
110

    
111
	public void insertRecords(final String resolver, final List<ResolvedObject> resolvedObjects) {
112
		resolvedObjects.forEach(it -> insertRecord(resolver, it));
113
	}
114

    
115
    public ResolvedObject getRecord(final String dnetIdentifier) {
116
        if (this.resolverCollection == null) {
117
            checkIntegrityCollection();
118
        }
119
        final Bson query = (Bson) QueryBuilder.start("dnet_identifier").is(dnetIdentifier).get();
120
        final FindIterable<DBObject> dbObjects = this.resolverCollection.find(query);
121
        if (dbObjects != null) {
122
            MongoCursor<DBObject> iterator = dbObjects.iterator();
123
			if (iterator.hasNext()) {
124
				final String body = iterator.next().get("body").toString();
125
				final ResolvedObject obj = objectFactory.generateObjectFromJson(body);
126
				return obj;
127
            }
128
        }
129
        return null;
130
    }
131

    
132
	public ResolvedObject getRecord(final String pid, final String pidType) {
133
		if (this.resolverCollection == null) {
134
			checkIntegrityCollection();
135
		}
136

    
137
        final Bson query = (Bson) QueryBuilder.start("pid").is(pid.toLowerCase()).and("pid_type").is(pidType.toLowerCase()).get();
138
        final FindIterable<DBObject> dbObjects = this.resolverCollection.find(query);
139
		if (dbObjects != null) {
140
			final List<ResolvedObject> rList = new ArrayList<>();
141
			dbObjects.forEach((Block<DBObject>) it -> {
142
				final String body = it.get("body").toString();
143
				ResolvedObject obj = objectFactory.generateObjectFromJson(it.get("body").toString());
144
				rList.add(obj);
145
			});
146
			if (rList.size() > 0) {
147
				return rList.get(0);
148
			}
149
		}
150
		return null;
151
	}
152

    
153
    public String getRecordIdentifier(final String dnetId) {
154
        double start = 0;
155
        try {
156
            if (this.resolverCollection == null) {
157
                checkIntegrityCollection();
158
            }
159
            start = System.currentTimeMillis();
160
            final Bson query = (Bson) QueryBuilder.start().put("dnet_identifier").is(dnetId).get();
161
            final FindIterable<DBObject> dbObjects = this.resolverCollection.find(query);
162
            if (dbObjects != null && dbObjects.iterator().hasNext()) {
163
                return dnetId;
164
            }
165
            return null;
166
        } finally {
167
            double total = System.currentTimeMillis() - start;
168
            log.debug("Request fetched in " + total + " ms");
169
        }
170
    }
171

    
172
	public String getRecordIdentifier(final String pid, final String pidType) {
173
		double start = 0;
174
		try {
175
			if (this.resolverCollection == null) {
176
				checkIntegrityCollection();
177
			}
178
			start = System.currentTimeMillis();
179
			final Bson query = (Bson) QueryBuilder.start().put("pid").is(pid).and("pid_type").is(pidType).get();
180
			final FindIterable<DBObject> dbObjects = this.resolverCollection.find(query);
181
			if (dbObjects != null) {
182
				for (DBObject obj : dbObjects) {
183
					final String id = obj.get("dnet_identifier").toString();
184
					if (id != null && !StringUtils.isBlank(id))
185
						return id;
186
				}
187
			}
188
			return null;
189
		} finally {
190
			double total = System.currentTimeMillis() - start;
191
			log.debug("Request fetched in " + total + " ms");
192
		}
193
	}
194

    
195
	public Iterable<ResolvedObject> getAllRecords() {
196
		try {
197
			if (this.resolverCollection == null) {
198
				checkIntegrityCollection();
199
			}
200
			final FindIterable<DBObject> dbObjects = this.resolverCollection.find();
201
			return () -> DnetStreamSupport.generateStreamFromIterator(dbObjects.iterator()).map(it ->
202
					objectFactory.generateObjectFromJson(it.get("body").toString())
203
			).iterator();
204
		} catch (Exception e) {
205
			return null;
206
		}
207
	}
208

    
209
	public MongoDatabase getMongoDatabase() {
210

    
211
		if (mongoDatabase == null) {
212
			mongoDatabase = mongoClient.getDatabase(getDatabaseName());
213
		}
214
		return mongoDatabase;
215
	}
216

    
217
	public void setMongoDatabase(final MongoDatabase mongoDatabase) {
218
		this.mongoDatabase = mongoDatabase;
219
	}
220

    
221
	public MongoCollection<DBObject> getResolverCollection() {
222
		return resolverCollection;
223
	}
224

    
225
	public void setResolverCollection(final MongoCollection<DBObject> resolverCollection) {
226
		this.resolverCollection = resolverCollection;
227
	}
228

    
229
	public String getCollectionName() {
230
		return collectionName;
231
	}
232

    
233
	@Required
234
	public void setCollectionName(final String collectionName) {
235
		this.collectionName = collectionName;
236
	}
237

    
238
	public String getDatabaseName() {
239
		return databaseName;
240
	}
241

    
242
	@Required
243
	public void setDatabaseName(final String databaseName) {
244
		this.databaseName = databaseName;
245
	}
246

    
247
	public MongoClient getMongoClient() {
248
		return mongoClient;
249
	}
250

    
251
	@Required
252
	public void setMongoClient(final MongoClient mongoClient) {
253
		this.mongoClient = mongoClient;
254
	}
255
}
    (1-1/1)