source: AnnotationManagerN4J/src/main/java/de/mpiwg/itgroup/annotations/restlet/BaseRestlet.java @ 22:b1fb0d117877

Last change on this file since 22:b1fb0d117877 was 22:b1fb0d117877, checked in by casties, 12 years ago

adding and listing groups via html works now.
no editing of group membership yet.
no authentication yet.

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