Project

General

Profile

Download (7.68 KB) Statistics
| Branch: | Tag: | Revision:
1
// $Id$
2
/**
3
* Copyright (C) 2015 EDIT
4
* European Distributed Institute of Taxonomy
5
* http://www.e-taxonomy.eu
6
*
7
* The contents of this file are subject to the Mozilla Public License Version 1.1
8
* See LICENSE.TXT at the top of this package for the full license terms.
9
*/
10
package org.cybertaxonomy.utis.store;
11

    
12
import java.io.IOException;
13
import java.net.URI;
14
import java.net.URISyntaxException;
15
import java.util.Date;
16
import java.util.List;
17

    
18
import org.apache.commons.httpclient.util.DateParseException;
19
import org.apache.commons.httpclient.util.DateUtil;
20
import org.apache.http.Header;
21
import org.apache.http.HttpResponse;
22
import org.apache.http.client.ClientProtocolException;
23
import org.apache.http.client.methods.HttpHead;
24
import org.apache.http.impl.client.CloseableHttpClient;
25
import org.apache.http.impl.client.HttpClientBuilder;
26
import org.cybertaxonomy.utis.checklist.DRFChecklistException;
27
import org.slf4j.Logger;
28
import org.slf4j.LoggerFactory;
29

    
30
/**
31
 * @author a.kohlbecker
32
 * @date Oct 28, 2015
33
 *
34
 */
35
public class Neo4jStoreUpdater {
36

    
37
    private static final String SKIP_STORE_UPDATING = "skipStoreUpdating";
38

    
39
    protected Logger logger = LoggerFactory.getLogger(Neo4jStoreUpdater.class);
40

    
41
    private final URI testUrl;
42
    private final Neo4jStore store;
43
    private long interval_ms;
44
    private boolean incrementalUpdate = false;
45

    
46

    
47
    private LastModifiedProvider lastModifiedProvider;
48

    
49
    private ResourceProvider resourceProvider;
50

    
51
    /**
52
     * @return the lastModifiedProvider
53
     */
54
    public LastModifiedProvider getLastModifiedProvider() {
55
        return lastModifiedProvider;
56
    }
57

    
58
    /**
59
     * @param lastModifiedProvider the lastModifiedProvider to set
60
     */
61
    public void setLastModifiedProvider(LastModifiedProvider lastModifiedProvider) {
62
        this.lastModifiedProvider = lastModifiedProvider;
63
    }
64

    
65
    /**
66
     * @param resourceProvider
67
     */
68
    public void setResourceProvider(ResourceProvider resourceProvider) {
69
        this.resourceProvider = resourceProvider;
70

    
71
    }
72

    
73
    public Neo4jStoreUpdater(Neo4jStore store, String testUrl) throws URISyntaxException {
74
        this.testUrl = new URI(testUrl);
75
        this.store = store;
76
    }
77

    
78
    /**
79
     * @param lastModified
80
     * @return
81
     */
82
    private Date getRemoteLastModified() {
83

    
84
        Date lastModified = null;
85
        if(lastModifiedProvider != null){
86
            try {
87
                return lastModifiedProvider.getLastModified();
88
            } catch (DRFChecklistException e) {
89
                logger.error("Error in LastModifiedProvider, if this problem persists it will block from updating neo4jStore", e);
90
            }
91
        } else {
92

    
93
            CloseableHttpClient client = HttpClientBuilder.create().build();
94
            HttpHead request = new HttpHead(testUrl);
95
            try {
96
                HttpResponse response = client.execute(request);
97
                Header lastModifiedH = response.getFirstHeader("Last-Modified");
98
                lastModified = DateUtil.parseDate(lastModifiedH.getValue());
99
                logger.debug("Last-Modified: " + lastModifiedH.getValue());
100

    
101
            } catch (ClientProtocolException e) {
102
                logger.error("ClientProtocolException, if this problem persists it will block from updating neo4jStore", e);
103
            } catch (DateParseException e) {
104
                logger.error("Could not parse Last-Modified value from HTTP response, if this problem persists it will block from updating neo4jStore");
105
            } catch (IOException e) {
106
                logger.error("IOException, if this problem persists it will block from updating the neo4jStore", e);
107
            } finally {
108
                try {
109
                    client.close();
110
                } catch (IOException e) {
111
                    // IGNORE //
112
                }
113
            }
114
        }
115
        return lastModified;
116
    }
117

    
118
    private Date checkNewerVersion() {
119

    
120
        logger.info("polling for updates at " + testUrl.toString());
121
        Date lastModified = getRemoteLastModified();
122
        if(store.getLastModified() == null || lastModified != null && lastModified.after(store.getLastModified())) {
123
            logger.info("remote resource is more recent:  " + DateUtil.formatDate(lastModified));
124
            return lastModified;
125
        }
126
        return null;
127
    }
128

    
129
    public void watch(int intervalMinutes) {
130

    
131
        if (isRunningAsTest()) {
132
            logger.warn("triggering update in test mode");
133
            updateIfNeeded();
134
        } else {
135

    
136
            if(System.getProperty(SKIP_STORE_UPDATING) == null){
137

    
138
                this.interval_ms = 1000 * 60 * intervalMinutes;
139
                Thread updateThread = new Thread() {
140

    
141
                    @Override
142
                    public void run() {
143
                        boolean interrupted = false;
144
                        while (!interrupted) {
145
                            logger.warn("triggering update in update thread in 100ms");
146
                            try {
147
                                sleep(100);
148
                            } catch (InterruptedException e) {
149
                                logger.info("Neo4jStoreUpdater has been interrupted");
150
                                interrupted = true;
151
                            }
152
                            updateIfNeeded();
153
                            try {
154
                                sleep(interval_ms);
155
                            } catch (InterruptedException e) {
156
                                logger.info("Neo4jStoreUpdater has been interrupted");
157
                                interrupted = true;
158
                            }
159
                        }
160
                    }
161
                };
162
                updateThread.setName(Neo4jStoreUpdater.class.getSimpleName());
163
                updateThread.setPriority(Thread.MIN_PRIORITY);
164
                updateThread.start();
165
            } else {
166
                logger.info("**********************************************");
167
                logger.info(" store updating disabled by system sproperty");
168
                logger.info("**********************************************");
169
            }
170
        }
171
    }
172

    
173

    
174

    
175
    /**
176
     * @return
177
     */
178
    private boolean isRunningAsTest() {
179
        StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
180
        for (StackTraceElement stackTraceElement : stackTrace) {
181
            if(stackTraceElement.getClassName().startsWith("org.junit.runners")) {
182
                return true;
183
            }
184
        }
185
        return false;
186
    }
187

    
188
    /**
189
     *
190
     * @param newLastModified The new last modified time stamp to set for the store
191
     */
192
    public void updateStore(Date newLastModified) {
193

    
194
        if(store.hasActiveImport()){
195
            logger.warn("The store (" + store.storeLocation.getPath() + ") has an active import, skipping this update");
196
        }
197

    
198
        logger.info("Starting store update");
199
        try {
200
            List<URI> resources = resourceProvider.getResources(store.getLastModified());
201
            store.loadIntoStore(resources, !isIncrementalUpdate());
202
            store.setLastModified(newLastModified);
203
        } catch (Exception e) {
204
            throw new RuntimeException("Loading resources into Neo4jStore failed", e);
205
        }
206

    
207

    
208
        logger.info("Store update done.");
209
    }
210

    
211
    /**
212
     *
213
     */
214
    public void updateIfNeeded() {
215
        Date lastModified = checkNewerVersion();
216
        if(lastModified != null) {
217
            updateStore(lastModified);
218
        }
219
    }
220

    
221
    /**
222
     * @return the incrementalUpdate
223
     */
224
    public boolean isIncrementalUpdate() {
225
        return incrementalUpdate;
226
    }
227

    
228
    /**
229
     * @param incrementalUpdate the incrementalUpdate to set
230
     */
231
    public void setIncrementalUpdate(boolean incrementalUpdate) {
232
        this.incrementalUpdate = incrementalUpdate;
233
    }
234

    
235
}
(4-4/9)