source: AnnotationManagerN4J/src/main/java/de/mpiwg/itgroup/annotations/restlet/BaseRestlet.java @ 66:5b568de5ee0d

Last change on this file since 66:5b568de5ee0d was 66:5b568de5ee0d, checked in by casties, 10 years ago

updated to new Neo4J version 2.0. doesn't use new features. problems with neo4j admin web ui.

File size: 13.9 KB
Line 
1package de.mpiwg.itgroup.annotations.restlet;
2
3import java.io.File;
4import java.io.FileInputStream;
5import java.io.FileNotFoundException;
6import java.io.IOException;
7import java.io.InputStream;
8import java.util.Hashtable;
9import java.util.Properties;
10
11import javax.naming.NamingEnumeration;
12import javax.naming.NamingException;
13import javax.naming.directory.Attribute;
14import javax.naming.directory.DirContext;
15import javax.naming.directory.InitialDirContext;
16import javax.naming.directory.SearchControls;
17import javax.naming.directory.SearchResult;
18import javax.servlet.ServletContext;
19
20import org.apache.log4j.BasicConfigurator;
21import org.apache.log4j.Logger;
22import org.neo4j.graphdb.GraphDatabaseService;
23import org.neo4j.graphdb.factory.GraphDatabaseBuilder;
24import org.neo4j.graphdb.factory.GraphDatabaseFactory;
25import org.neo4j.graphdb.factory.GraphDatabaseSettings;
26import org.neo4j.kernel.AbstractGraphDatabase;
27import org.neo4j.kernel.GraphDatabaseAPI;
28import org.neo4j.server.WrappingNeoServerBootstrapper;
29import org.restlet.Application;
30import org.restlet.Context;
31
32import de.mpiwg.itgroup.annotations.neo4j.AnnotationStore;
33
34public abstract class BaseRestlet extends Application {
35
36    public static Logger logger = Logger.getLogger(BaseRestlet.class);
37
38    /**
39     * Properties holding consumer keys and secrets.
40     */
41    protected Properties consumerKeys;
42    public String CONSUMER_KEYS_PATH = "WEB-INF/consumerkeys.property";
43    public static final String CONSUMERKEYS_KEY = "annotationmanager.consumerkeys";
44
45    /**
46     * Properties holding server config.
47     */
48    protected Properties serverConfig;
49    public String CONFIG_PROPS_PATH = "WEB-INF/serverconfig.property";
50    public static final String SERVERCONFIG_KEY = "annotationmanager.serverconfig";
51
52    /**
53     * database instance;
54     */
55    protected GraphDatabaseService graphDb;
56    public static final String GRAPHDB_KEY = "annotationmanager.graphdb";
57    public static final String GRAPHDB_PATH_KEY = "annotationmanager.graphdb.path";
58    public String graphdbPath = "WEB-INF/neo4j-annotation-db";
59
60    /**
61     * database interface server instance.
62     */
63    protected WrappingNeoServerBootstrapper srv;
64    public static final String GRAPHDBSRV_KEY = "annotationmanager.graphdb.srv";
65
66    /**
67     * annotation store instance.
68     */
69    protected AnnotationStore store;
70    public static final String ANNSTORE_KEY = "annotationmanager.store";
71
72    /**
73     * LDAP server URI (for looking up full user names).
74     */
75    protected String ldapServerUrl;
76    public static final String LDAP_SERVER_KEY = "annotationmanager.ldapserver.url";
77
78    public static final String ADMIN_USER_KEY = "annotationmanager.admin.user";
79    public static final String ADMIN_PASSWORD_KEY = "annotationmanager.admin.password";
80
81    /**
82     * run in authorization mode i.e. with tokens.
83     */
84    protected boolean authorizationMode = false;
85    public static final String AUTHORIZATION_MODE_KEY = "annotationmanager.authorization";
86   
87    /**
88     * prefix to create uris for tags in store.
89     */
90    public static String TAGS_URI_PREFIX = "";
91    public static final String TAGS_URI_KEY = "annotationmanager.uris.tags";
92
93    /**
94     * prefix to create uris for persons in store.
95     */
96    public static String PERSONS_URI_PREFIX = "";
97    public static final String PERSONS_URI_KEY = "annotationmanager.uris.persons";
98
99    /**
100     * prefix to create uris for groups in store.
101     */
102    public static String GROUPS_URI_PREFIX = ""; 
103    public static final String GROUPS_URI_KEY = "annotationmanager.uris.groups";
104
105    public static final String ANNOTATIONS_URI_KEY = "annotationmanager.uris.annotations";
106
107    /**
108     * constructor
109     *
110     * @param context
111     */
112    public BaseRestlet(Context context) {
113        super(context);
114        configure();
115    }
116
117    /**
118     * Configures the restlet.
119     * Reads serverConfig, consumerKeys and graphDb config from config files and starts graphDb.
120     * Uses config from webapp context if already initialized.
121     */
122    protected void configure() {
123        ServletContext sc = (ServletContext) getContext().getServerDispatcher().getContext().getAttributes()
124                .get("org.restlet.ext.servlet.ServletContext");
125        if (sc != null) {
126            if (sc.getAttribute("annotationserver.log4j.configured") == null) {
127                // TODO: is this the right place to run the log4j configurator?
128                BasicConfigurator.configure();
129                sc.setAttribute("annotationserver.log4j.configured", "done");
130            }
131            logger.info(getVersion() + " starting...");
132
133            /*
134             * read config from webapp
135             */
136            serverConfig = (Properties) sc.getAttribute(SERVERCONFIG_KEY);
137            if (serverConfig == null) {
138                serverConfig = new Properties();
139                InputStream ps = getResourceAsStream(sc, CONFIG_PROPS_PATH);
140                if (ps != null) {
141                    logger.debug("loading config from " + CONFIG_PROPS_PATH);
142                    try {
143                        serverConfig.load(ps);
144                        /*
145                         * read serverconfig options
146                         */
147                        graphdbPath = serverConfig.getProperty(GRAPHDB_PATH_KEY, graphdbPath);
148                        ldapServerUrl = serverConfig.getProperty(LDAP_SERVER_KEY, null);
149                        /*
150                         * uri prefixes
151                         */
152                        if (serverConfig.containsKey(PERSONS_URI_KEY)) {
153                            BaseRestlet.PERSONS_URI_PREFIX = serverConfig.getProperty(PERSONS_URI_KEY);
154                        }
155                        if (serverConfig.containsKey(GROUPS_URI_KEY)) {
156                            BaseRestlet.GROUPS_URI_PREFIX = serverConfig.getProperty(GROUPS_URI_KEY);
157                        }
158                        if (serverConfig.containsKey(TAGS_URI_KEY)) {
159                            BaseRestlet.TAGS_URI_PREFIX = serverConfig.getProperty(TAGS_URI_KEY);
160                        }
161                        if (serverConfig.containsKey(ANNOTATIONS_URI_KEY)) {
162                            AnnotationStore.ANNOTATION_URI_PREFIX = serverConfig.getProperty(ANNOTATIONS_URI_KEY);
163                        }
164                    } catch (IOException e) {
165                        logger.warn("Error loading server config: ", e);
166                    }
167                    logger.debug("config: " + serverConfig);
168                } else {
169                    logger.error("Unable to get resource " + CONFIG_PROPS_PATH);
170                }
171                // store config
172                sc.setAttribute(SERVERCONFIG_KEY, serverConfig);
173            }
174            // look for database service in context
175            graphDb = (GraphDatabaseService) sc.getAttribute(GRAPHDB_KEY);
176            if (graphDb == null) {
177                /*
178                 * open database
179                 */
180                String dbFn = getResourcePath(sc, graphdbPath);
181                if (dbFn != null) {
182                    logger.debug("opening DB " + dbFn);
183                    GraphDatabaseBuilder graphDbBuilder = new GraphDatabaseFactory().newEmbeddedDatabaseBuilder(dbFn);
184                    graphDbBuilder.setConfig(GraphDatabaseSettings.allow_store_upgrade, "true");
185                    graphDb = graphDbBuilder.newGraphDatabase();
186                    registerShutdownHook(graphDb);
187                    // store in context
188                    sc.setAttribute(GRAPHDB_KEY, graphDb);
189                    // AnnotationStore
190                    store = new AnnotationStore(graphDb);
191                    sc.setAttribute(ANNSTORE_KEY, store);
192                    // admin server
193                    srv = new WrappingNeoServerBootstrapper((GraphDatabaseAPI) graphDb);
194                    logger.debug("Starting DB admin server...");
195                    // store in context
196                    sc.setAttribute(GRAPHDBSRV_KEY, srv);
197                    srv.start();
198                } else {
199                    logger.error("Unable to get resource " + dbFn);
200                }
201            } else {
202                // get existing AnnotationStore
203                store = (AnnotationStore) sc.getAttribute(ANNSTORE_KEY);
204            }
205            /*
206             * read consumerKeys from webapp
207             */
208            consumerKeys = (Properties) sc.getAttribute(CONSUMERKEYS_KEY);
209            if (consumerKeys == null) {
210                consumerKeys = new Properties();
211                InputStream ps = getResourceAsStream(sc, CONSUMER_KEYS_PATH);
212                if (ps != null) {
213                    logger.debug("loading consumer keys from " + CONSUMER_KEYS_PATH);
214                    try {
215                        consumerKeys.load(ps);
216                    } catch (IOException e) {
217                        // TODO Auto-generated catch block
218                        e.printStackTrace();
219                    }
220                    logger.debug("consumer keys: " + consumerKeys);
221                } else {
222                    logger.error("Unable to get resource " + CONSUMER_KEYS_PATH);
223                }
224                // store config
225                sc.setAttribute(CONSUMERKEYS_KEY, consumerKeys);
226            }
227        } else {
228            logger.error("Unable to get ServletContext!");
229        }
230    }
231
232    public abstract String getVersion();
233
234    /**
235     * @return the authorizationMode
236     */
237    public boolean isAuthorizationMode() {
238        return authorizationMode;
239    }
240
241    /**
242     * @return the store
243     */
244    public AnnotationStore getAnnotationStore() {
245        return store;
246    }
247
248    /**
249     * returns consumer secret for consumer key. returns null if consumer key
250     * doesn't exist.
251     *
252     * @param consumerKey
253     * @return
254     */
255    public String getConsumerSecret(String consumerKey) {
256        return consumerKeys.getProperty(consumerKey);
257    }
258
259    /**
260     * Hole den vollen Benutzernamen aus dem LDAP
261     *
262     * @param creator
263     * @return
264     */
265    public String getFullNameFromLdap(String creator) {
266        String retString = creator; // falls nichts gefunden wird einfach den
267                                    // creator zurueckgeben
268        if (ldapServerUrl == null) {
269            return retString;
270        }
271        Hashtable<String, String> env = new Hashtable<String, String>();
272        String sp = "com.sun.jndi.ldap.LdapCtxFactory";
273        env.put(javax.naming.Context.INITIAL_CONTEXT_FACTORY, sp);
274        env.put(javax.naming.Context.PROVIDER_URL, ldapServerUrl);
275
276        DirContext dctx;
277        try {
278            dctx = new InitialDirContext(env);
279        } catch (NamingException e) {
280            logger.error("Error in getFullNameFromLDAP!", e);
281            return retString;
282        }
283
284        String base = "ou=people";
285
286        SearchControls sc = new SearchControls();
287        String[] attributeFilter = { "cn", "mail" };
288        sc.setReturningAttributes(attributeFilter);
289        sc.setSearchScope(SearchControls.SUBTREE_SCOPE);
290
291        String filter = "(uid=" + creator + ")";
292
293        try {
294            NamingEnumeration<SearchResult> results = dctx.search(base, filter, sc);
295            while (results.hasMore()) {
296                SearchResult sr = (SearchResult) results.next();
297                javax.naming.directory.Attributes attrs = sr.getAttributes();
298
299                Attribute attr = attrs.get("cn");
300                retString = (String) attr.get();
301            }
302        } catch (NamingException e) {
303            logger.error("Error in getFullNameFromLDAP!", e);
304        }
305
306        try {
307            dctx.close();
308        } catch (NamingException e) {
309            logger.error("Error in getFullNameFromLDAP!", e);
310        }
311        return retString;
312    }
313
314    /**
315     * returns resource from path (in webapp) as InputStream.
316     *
317     * @param sc
318     * @param path
319     * @return
320     */
321    protected InputStream getResourceAsStream(ServletContext sc, String path) {
322        InputStream ps = sc.getResourceAsStream(path);
323        if (ps == null) {
324            // try as file
325            File pf = new File(sc.getRealPath(path));
326            if (pf != null) {
327                logger.debug("trying file for: " + pf);
328                try {
329                    ps = new FileInputStream(pf);
330                } catch (FileNotFoundException e) {
331                    logger.error(e);
332                }
333            }
334        }
335        return ps;
336    }
337
338    /**
339     * get a real file name for a web app file pathname.
340     *
341     * If filename starts with "/" its treated as absolute else the path is
342     * appended to the base directory of the web-app.
343     *
344     * @param filename
345     * @param sc
346     * @return
347     */
348    public static String getResourcePath(ServletContext sc, String filename) {
349        File f = new File(filename);
350        // is the filename absolute?
351        if (!f.isAbsolute()) {
352            // relative path -> use getRealPath to resolve in webapp
353            filename = sc.getRealPath(filename);
354        }
355        return filename;
356    }
357
358    /*
359     * (non-Javadoc)
360     *
361     * @see org.restlet.Application#stop()
362     */
363    @Override
364    public synchronized void stop() throws Exception {
365        /*
366         * trying to clean up databases, not sure if this is the right way...
367         */
368        if (srv != null) {
369            logger.debug("Stopping DB admin server...");
370            srv.stop();
371            srv = null;
372        }
373        if (graphDb != null) {
374            logger.debug("Stopping DB...");
375            graphDb.shutdown();
376            graphDb = null;
377        }
378        super.stop();
379    }
380
381    private static void registerShutdownHook(final GraphDatabaseService graphDb) {
382        // Registers a shutdown hook for the Neo4j instance so that it
383        // shuts down nicely when the VM exits (even if you "Ctrl-C" the
384        // running example before it's completed)
385        Runtime.getRuntime().addShutdownHook(new Thread() {
386            @Override
387            public void run() {
388                graphDb.shutdown();
389            }
390        });
391    }
392
393}
Note: See TracBrowser for help on using the repository browser.