source: AnnotationManagerN4J/src/main/java/de/mpiwg/itgroup/annotations/restlet/BaseRestlet.java @ 57:4efb21cf0ce0

Last change on this file since 57:4efb21cf0ce0 was 57:4efb21cf0ce0, checked in by casties, 11 years ago

new non-authorized mode without tokens. enabled by default. configured with annotationmanager.authorization=false property.

File size: 12.0 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     * constructor
86     *
87     * @param context
88     */
89    public BaseRestlet(Context context) {
90        super(context);
91        configure();
92    }
93
94    /**
95     * Configures the restlet.
96     * Reads serverConfig, consumerKeys and graphDb config from config files and starts graphDb.
97     * Uses config from webapp context if already initialized.
98     */
99    protected void configure() {
100        ServletContext sc = (ServletContext) getContext().getServerDispatcher().getContext().getAttributes()
101                .get("org.restlet.ext.servlet.ServletContext");
102        if (sc != null) {
103            if (sc.getAttribute("annotationserver.log4j.configured") == null) {
104                // TODO: is this the right place to run the log4j configurator?
105                BasicConfigurator.configure();
106                sc.setAttribute("annotationserver.log4j.configured", "done");
107            }
108            logger.info(getVersion() + " starting...");
109
110            /*
111             * read config from webapp
112             */
113            serverConfig = (Properties) sc.getAttribute(SERVERCONFIG_KEY);
114            if (serverConfig == null) {
115                serverConfig = new Properties();
116                InputStream ps = getResourceAsStream(sc, CONFIG_PROPS_PATH);
117                if (ps != null) {
118                    logger.debug("loading config from " + CONFIG_PROPS_PATH);
119                    try {
120                        serverConfig.load(ps);
121                        /*
122                         * read serverconfig options
123                         */
124                        graphdbPath = serverConfig.getProperty(GRAPHDB_PATH_KEY, graphdbPath);
125                        ldapServerUrl = serverConfig.getProperty(LDAP_SERVER_KEY, null);
126                    } catch (IOException e) {
127                        logger.warn("Error loading server config: ", e);
128                    }
129                    logger.debug("config: " + serverConfig);
130                } else {
131                    logger.error("Unable to get resource " + CONFIG_PROPS_PATH);
132                }
133                // store config
134                sc.setAttribute(SERVERCONFIG_KEY, serverConfig);
135            }
136            // look for database service in context
137            graphDb = (GraphDatabaseService) sc.getAttribute(GRAPHDB_KEY);
138            if (graphDb == null) {
139                /*
140                 * open database
141                 */
142                String dbFn = getResourcePath(sc, graphdbPath);
143                if (dbFn != null) {
144                    logger.debug("opening DB " + dbFn);
145                    graphDb = new GraphDatabaseFactory().newEmbeddedDatabase(dbFn);
146                    registerShutdownHook(graphDb);
147                    // store in context
148                    sc.setAttribute(GRAPHDB_KEY, graphDb);
149                    // AnnotationStore
150                    store = new AnnotationStore(graphDb);
151                    sc.setAttribute(ANNSTORE_KEY, store);
152                    // admin server
153                    srv = new WrappingNeoServerBootstrapper((AbstractGraphDatabase) graphDb);
154                    logger.debug("Starting DB admin server...");
155                    // store in context
156                    sc.setAttribute(GRAPHDBSRV_KEY, srv);
157                    srv.start();
158                } else {
159                    logger.error("Unable to get resource " + dbFn);
160                }
161            } else {
162                // get existing AnnotationStore
163                store = (AnnotationStore) sc.getAttribute(ANNSTORE_KEY);
164            }
165            /*
166             * read consumerKeys from webapp
167             */
168            consumerKeys = (Properties) sc.getAttribute(CONSUMERKEYS_KEY);
169            if (consumerKeys == null) {
170                consumerKeys = new Properties();
171                InputStream ps = getResourceAsStream(sc, CONSUMER_KEYS_PATH);
172                if (ps != null) {
173                    logger.debug("loading consumer keys from " + CONSUMER_KEYS_PATH);
174                    try {
175                        consumerKeys.load(ps);
176                    } catch (IOException e) {
177                        // TODO Auto-generated catch block
178                        e.printStackTrace();
179                    }
180                    logger.debug("consumer keys: " + consumerKeys);
181                } else {
182                    logger.error("Unable to get resource " + CONSUMER_KEYS_PATH);
183                }
184                // store config
185                sc.setAttribute(CONSUMERKEYS_KEY, consumerKeys);
186            }
187        } else {
188            logger.error("Unable to get ServletContext!");
189        }
190    }
191
192    public abstract String getVersion();
193
194    /**
195     * @return the authorizationMode
196     */
197    public boolean isAuthorizationMode() {
198        return authorizationMode;
199    }
200
201    /**
202     * @return the store
203     */
204    public AnnotationStore getAnnotationStore() {
205        return store;
206    }
207
208    /**
209     * returns consumer secret for consumer key. returns null if consumer key
210     * doesn't exist.
211     *
212     * @param consumerKey
213     * @return
214     */
215    public String getConsumerSecret(String consumerKey) {
216        return consumerKeys.getProperty(consumerKey);
217    }
218
219    /**
220     * Hole den vollen Benutzernamen aus dem LDAP
221     *
222     * @param creator
223     * @return
224     */
225    public String getFullNameFromLdap(String creator) {
226        String retString = creator; // falls nichts gefunden wird einfach den
227                                    // creator zurueckgeben
228        if (ldapServerUrl == null) {
229            return retString;
230        }
231        Hashtable<String, String> env = new Hashtable<String, String>();
232        String sp = "com.sun.jndi.ldap.LdapCtxFactory";
233        env.put(javax.naming.Context.INITIAL_CONTEXT_FACTORY, sp);
234        env.put(javax.naming.Context.PROVIDER_URL, ldapServerUrl);
235
236        DirContext dctx;
237        try {
238            dctx = new InitialDirContext(env);
239        } catch (NamingException e) {
240            logger.error("Error in getFullNameFromLDAP!", e);
241            return retString;
242        }
243
244        String base = "ou=people";
245
246        SearchControls sc = new SearchControls();
247        String[] attributeFilter = { "cn", "mail" };
248        sc.setReturningAttributes(attributeFilter);
249        sc.setSearchScope(SearchControls.SUBTREE_SCOPE);
250
251        String filter = "(uid=" + creator + ")";
252
253        try {
254            NamingEnumeration<SearchResult> results = dctx.search(base, filter, sc);
255            while (results.hasMore()) {
256                SearchResult sr = (SearchResult) results.next();
257                javax.naming.directory.Attributes attrs = sr.getAttributes();
258
259                Attribute attr = attrs.get("cn");
260                retString = (String) attr.get();
261            }
262        } catch (NamingException e) {
263            logger.error("Error in getFullNameFromLDAP!", e);
264        }
265
266        try {
267            dctx.close();
268        } catch (NamingException e) {
269            logger.error("Error in getFullNameFromLDAP!", e);
270        }
271        return retString;
272    }
273
274    /**
275     * returns resource from path (in webapp) as InputStream.
276     *
277     * @param sc
278     * @param path
279     * @return
280     */
281    protected InputStream getResourceAsStream(ServletContext sc, String path) {
282        InputStream ps = sc.getResourceAsStream(path);
283        if (ps == null) {
284            // try as file
285            File pf = new File(sc.getRealPath(path));
286            if (pf != null) {
287                logger.debug("trying file for: " + pf);
288                try {
289                    ps = new FileInputStream(pf);
290                } catch (FileNotFoundException e) {
291                    logger.error(e);
292                }
293            }
294        }
295        return ps;
296    }
297
298    /**
299     * get a real file name for a web app file pathname.
300     *
301     * If filename starts with "/" its treated as absolute else the path is
302     * appended to the base directory of the web-app.
303     *
304     * @param filename
305     * @param sc
306     * @return
307     */
308    public static String getResourcePath(ServletContext sc, String filename) {
309        File f = new File(filename);
310        // is the filename absolute?
311        if (!f.isAbsolute()) {
312            // relative path -> use getRealPath to resolve in webapp
313            filename = sc.getRealPath(filename);
314        }
315        return filename;
316    }
317
318    /*
319     * (non-Javadoc)
320     *
321     * @see org.restlet.Application#stop()
322     */
323    @Override
324    public synchronized void stop() throws Exception {
325        /*
326         * trying to clean up databases, not sure if this is the right way...
327         */
328        if (srv != null) {
329            logger.debug("Stopping DB admin server...");
330            srv.stop();
331            srv = null;
332        }
333        if (graphDb != null) {
334            logger.debug("Stopping DB...");
335            graphDb.shutdown();
336            graphDb = null;
337        }
338        super.stop();
339    }
340
341    private static void registerShutdownHook(final GraphDatabaseService graphDb) {
342        // Registers a shutdown hook for the Neo4j instance so that it
343        // shuts down nicely when the VM exits (even if you "Ctrl-C" the
344        // running example before it's completed)
345        Runtime.getRuntime().addShutdownHook(new Thread() {
346            @Override
347            public void run() {
348                graphDb.shutdown();
349            }
350        });
351    }
352
353}
Note: See TracBrowser for help on using the repository browser.