source: AnnotationManagerN4J/src/main/java/de/mpiwg/itgroup/annotations/restlet/BaseRestlet.java @ 59:e2f86ef9b871

Last change on this file since 59:e2f86ef9b871 was 59:e2f86ef9b871, checked in by casties, 11 years ago

make annotation uri in store configurable. fix npe with no tags.

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