1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.neo4j.server.rest.web;
21
22 import org.neo4j.graphdb.GraphDatabaseService;
23 import org.neo4j.graphdb.Node;
24 import org.neo4j.graphdb.NotFoundException;
25 import org.neo4j.graphdb.Relationship;
26 import org.neo4j.kernel.AbstractGraphDatabase;
27 import org.neo4j.server.database.Database;
28 import org.neo4j.server.plugins.BadPluginInvocationException;
29 import org.neo4j.server.plugins.ParameterList;
30 import org.neo4j.server.plugins.PluginInvocationFailureException;
31 import org.neo4j.server.plugins.PluginInvocator;
32 import org.neo4j.server.plugins.PluginLookupException;
33 import org.neo4j.server.rest.repr.BadInputException;
34 import org.neo4j.server.rest.repr.InputFormat;
35 import org.neo4j.server.rest.repr.MappingRepresentation;
36 import org.neo4j.server.rest.repr.MappingSerializer;
37 import org.neo4j.server.rest.repr.OutputFormat;
38 import org.neo4j.server.rest.repr.Representation;
39 import org.neo4j.server.rest.repr.ServerExtensionRepresentation;
40
41 import javax.ws.rs.GET;
42 import javax.ws.rs.POST;
43 import javax.ws.rs.Path;
44 import javax.ws.rs.PathParam;
45 import javax.ws.rs.core.Context;
46 import javax.ws.rs.core.Response;
47
48 @Path( "ext" )
49 public class ExtensionService
50 {
51 private static final String PATH_EXTENSION = "/{name}";
52 private static final String PATH_GRAPHDB_EXTENSION_METHOD = PATH_EXTENSION
53 + "/graphdb/{method}";
54 private static final String PATH_NODE_EXTENSION_METHOD = PATH_EXTENSION + "/node/{nodeId}/{method}";
55 private static final String PATH_RELATIONSHIP_EXTENSION_METHOD = PATH_EXTENSION
56 + "/relationship/{relationshipId}/{method}";
57 private final InputFormat input;
58 private final OutputFormat output;
59 private final PluginInvocator extensions;
60 private final AbstractGraphDatabase graphDb;
61
62 public ExtensionService( @Context InputFormat input, @Context OutputFormat output,
63 @Context PluginInvocator extensions, @Context Database database )
64 {
65 this.input = input;
66 this.output = output;
67 this.extensions = extensions;
68 this.graphDb = database.graph;
69 }
70
71 private Node node( long id ) throws NodeNotFoundException
72 {
73 try
74 {
75 return graphDb.getNodeById( id );
76 }
77 catch ( NotFoundException e )
78 {
79 throw new NodeNotFoundException();
80 }
81 }
82
83 private Relationship relationship( long id ) throws RelationshipNotFoundException
84 {
85 try
86 {
87 return graphDb.getRelationshipById( id );
88 }
89 catch ( NotFoundException e )
90 {
91 throw new RelationshipNotFoundException();
92 }
93 }
94
95 @GET
96 public Response getExtensionsList()
97 {
98 return output.ok( this.extensionsList() );
99 }
100
101 @GET
102 @Path( PATH_EXTENSION )
103 public Response getExtensionList( @PathParam( "name" ) String name )
104 {
105 try
106 {
107 return output.ok( this.extensionList( name ) );
108 }
109 catch ( PluginLookupException e )
110 {
111 return output.notFound( e );
112 }
113 }
114
115 @POST
116 @Path( PATH_GRAPHDB_EXTENSION_METHOD )
117 public Response invokeGraphDatabaseExtension( @PathParam( "name" ) String name,
118 @PathParam( "method" ) String method, String data )
119 {
120 try
121 {
122 return output.ok( this.invokeGraphDatabaseExtension( name, method,
123 input.readParameterList( data ) ) );
124 }
125 catch ( BadInputException e )
126 {
127 return output.badRequest( e );
128 }
129 catch ( PluginLookupException e )
130 {
131 return output.notFound( e );
132 }
133 catch ( BadPluginInvocationException e )
134 {
135 return output.badRequest( e.getCause() );
136 }
137 catch ( PluginInvocationFailureException e )
138 {
139 return output.serverError( e.getCause() );
140 }
141 }
142
143 @GET
144 @Path( PATH_GRAPHDB_EXTENSION_METHOD )
145 public Response getGraphDatabaseExtensionDescription( @PathParam( "name" ) String name,
146 @PathParam( "method" ) String method )
147 {
148 try
149 {
150 return output.ok( this.describeGraphDatabaseExtension( name, method ) );
151 }
152 catch ( PluginLookupException e )
153 {
154 return output.notFound( e );
155 }
156 }
157
158 @POST
159 @Path( PATH_NODE_EXTENSION_METHOD )
160 public Response invokeNodeExtension( @PathParam( "name" ) String name,
161 @PathParam( "method" ) String method, @PathParam( "nodeId" ) long nodeId, String data )
162 {
163 try
164 {
165 return output.ok( this.invokeNodeExtension( nodeId, name, method,
166 input.readParameterList( data ) ) );
167 }
168 catch ( NodeNotFoundException e )
169 {
170 return output.notFound( e );
171 }
172 catch ( BadInputException e )
173 {
174 return output.badRequest( e );
175 }
176 catch ( PluginLookupException e )
177 {
178 return output.notFound( e );
179 }
180 catch ( BadPluginInvocationException e )
181 {
182 return output.badRequest( e.getCause() );
183 }
184 catch ( PluginInvocationFailureException e )
185 {
186 return output.serverError( e.getCause() );
187 }
188 }
189
190 @GET
191 @Path( PATH_NODE_EXTENSION_METHOD )
192 public Response getNodeExtensionDescription( @PathParam( "name" ) String name,
193 @PathParam( "method" ) String method, @PathParam( "nodeId" ) long nodeId )
194 {
195 try
196 {
197 return output.ok( this.describeNodeExtension( name, method ) );
198 }
199 catch ( PluginLookupException e )
200 {
201 return output.notFound( e );
202 }
203 }
204
205 @POST
206 @Path( PATH_RELATIONSHIP_EXTENSION_METHOD )
207 public Response invokeRelationshipExtension( @PathParam( "name" ) String name,
208 @PathParam( "method" ) String method,
209 @PathParam( "relationshipId" ) long relationshipId, String data )
210 {
211 try
212 {
213 return output.ok( this.invokeRelationshipExtension( relationshipId, name, method,
214 input.readParameterList( data ) ) );
215 }
216 catch ( RelationshipNotFoundException e )
217 {
218 return output.notFound( e );
219 }
220 catch ( BadInputException e )
221 {
222 return output.badRequest( e );
223 }
224 catch ( PluginLookupException e )
225 {
226 return output.notFound( e );
227 }
228 catch ( BadPluginInvocationException e )
229 {
230 return output.badRequest( e.getCause() );
231 }
232 catch ( PluginInvocationFailureException e )
233 {
234 return output.serverError( e.getCause() );
235 }
236 }
237
238 @GET
239 @Path( PATH_RELATIONSHIP_EXTENSION_METHOD )
240 public Response getRelationshipExtensionDescription( @PathParam( "name" ) String name,
241 @PathParam( "method" ) String method, @PathParam( "relationshipId" ) long relationshipId )
242 {
243 try
244 {
245 return output.ok( this.describeRelationshipExtension( name, method ) );
246 }
247 catch ( PluginLookupException e )
248 {
249 return output.notFound( e );
250 }
251 }
252
253
254
255 protected Representation extensionsList()
256 {
257 return new MappingRepresentation( "extensions" )
258 {
259 @Override
260 protected void serialize( MappingSerializer serializer )
261 {
262 for ( String extension : extensions.extensionNames() )
263 {
264 serializer.putUri( extension, "ext/" + extension );
265 }
266 }
267 };
268 }
269
270 protected Representation extensionList( String extensionName ) throws PluginLookupException
271 {
272 return new ServerExtensionRepresentation( extensionName,
273 extensions.describeAll( extensionName ) );
274 }
275
276 protected Representation invokeGraphDatabaseExtension( String extensionName, String method,
277 ParameterList data ) throws PluginLookupException, BadInputException,
278 PluginInvocationFailureException, BadPluginInvocationException
279 {
280 return extensions.invoke( graphDb, extensionName, GraphDatabaseService.class, method,
281 graphDb, data );
282 }
283
284 protected Representation describeGraphDatabaseExtension( String extensionName, String method )
285 throws PluginLookupException
286 {
287 return extensions.describe( extensionName, GraphDatabaseService.class, method );
288 }
289
290 protected Representation invokeNodeExtension( long nodeId, String extensionName, String method,
291 ParameterList data ) throws NodeNotFoundException, PluginLookupException,
292 BadInputException, PluginInvocationFailureException, BadPluginInvocationException
293 {
294 return extensions.invoke( graphDb, extensionName, Node.class, method, node( nodeId ), data );
295 }
296
297 protected Representation describeNodeExtension( String extensionName, String method )
298 throws PluginLookupException
299 {
300 return extensions.describe( extensionName, Node.class, method );
301 }
302
303 protected Representation invokeRelationshipExtension( long relationshipId,
304 String extensionName, String method, ParameterList data )
305 throws RelationshipNotFoundException, PluginLookupException, BadInputException,
306 PluginInvocationFailureException, BadPluginInvocationException
307 {
308 return extensions.invoke( graphDb, extensionName, Relationship.class, method,
309 relationship( relationshipId ), data );
310 }
311
312 protected Representation describeRelationshipExtension( String extensionName, String method )
313 throws PluginLookupException
314 {
315 return extensions.describe( extensionName, Relationship.class, method );
316 }
317 }