diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/RESTExceptionWrapper.java b/guacamole/src/main/java/org/apache/guacamole/rest/RESTExceptionWrapper.java index 736907d4c..f4de4066b 100644 --- a/guacamole/src/main/java/org/apache/guacamole/rest/RESTExceptionWrapper.java +++ b/guacamole/src/main/java/org/apache/guacamole/rest/RESTExceptionWrapper.java @@ -172,6 +172,11 @@ public class RESTExceptionWrapper implements MethodInterceptor { } + // Rethrow unchecked exceptions such that they are properly wrapped + catch (RuntimeException e) { + throw new GuacamoleException(e.getMessage(), e); + } + } // Additional credentials are needed @@ -267,17 +272,21 @@ public class RESTExceptionWrapper implements MethodInterceptor { // All other errors catch (GuacamoleException e) { - // Generate default message + // Log all reasonable details of exception String message = e.getMessage(); - if (message == null) - message = "Unexpected server error."; + if (message != null) + logger.error("Unexpected internal error: {}", message); + else + logger.error("An internal error occurred, but did not contain " + + "an error message. Enable debug-level logging for " + + "details."); - // Ensure internal errors are logged at the debug level + // Ensure internal errors are fully logged at the debug level logger.debug("Unexpected exception in REST endpoint.", e); throw new APIException( APIError.Type.INTERNAL_ERROR, - message + "Unexpected server error." ); } diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/activeconnection/ActiveConnectionDirectoryResource.java b/guacamole/src/main/java/org/apache/guacamole/rest/activeconnection/ActiveConnectionDirectoryResource.java new file mode 100644 index 000000000..a19b5dcb2 --- /dev/null +++ b/guacamole/src/main/java/org/apache/guacamole/rest/activeconnection/ActiveConnectionDirectoryResource.java @@ -0,0 +1,72 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.guacamole.rest.activeconnection; + +import com.google.inject.assistedinject.Assisted; +import com.google.inject.assistedinject.AssistedInject; +import javax.ws.rs.Consumes; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; +import org.apache.guacamole.net.auth.ActiveConnection; +import org.apache.guacamole.net.auth.Directory; +import org.apache.guacamole.net.auth.UserContext; +import org.apache.guacamole.rest.directory.DirectoryObjectResourceFactory; +import org.apache.guacamole.rest.directory.DirectoryObjectTranslator; +import org.apache.guacamole.rest.directory.DirectoryResource; + +/** + * A REST resource which abstracts the operations available on a Directory of + * ActiveConnections. + * + * @author Michael Jumper + */ +@Produces(MediaType.APPLICATION_JSON) +@Consumes(MediaType.APPLICATION_JSON) +public class ActiveConnectionDirectoryResource + extends DirectoryResource { + + /** + * Creates a new ActiveConnectionDirectoryResource which exposes the + * operations and subresources available for the given ActiveConnection + * Directory. + * + * @param userContext + * The UserContext associated with the given Directory. + * + * @param directory + * The Directory being exposed. + * + * @param translator + * A DirectoryObjectTranslator implementation which handles + * ActiveConnections. + * + * @param resourceFactory + * A factory which can be used to create instances of resources + * representing ActiveConnections. + */ + @AssistedInject + public ActiveConnectionDirectoryResource(@Assisted UserContext userContext, + @Assisted Directory directory, + DirectoryObjectTranslator translator, + DirectoryObjectResourceFactory resourceFactory) { + super(userContext, directory, translator, resourceFactory); + } + +} diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/activeconnection/ActiveConnectionModule.java b/guacamole/src/main/java/org/apache/guacamole/rest/activeconnection/ActiveConnectionModule.java index efecdde02..c5418c21d 100644 --- a/guacamole/src/main/java/org/apache/guacamole/rest/activeconnection/ActiveConnectionModule.java +++ b/guacamole/src/main/java/org/apache/guacamole/rest/activeconnection/ActiveConnectionModule.java @@ -27,6 +27,7 @@ import com.google.inject.assistedinject.FactoryModuleBuilder; import org.apache.guacamole.net.auth.ActiveConnection; import org.apache.guacamole.rest.directory.DirectoryObjectResource; import org.apache.guacamole.rest.directory.DirectoryObjectTranslator; +import org.apache.guacamole.rest.directory.DirectoryResource; /** * Guice Module which configures injections required for handling @@ -41,6 +42,10 @@ public class ActiveConnectionModule extends AbstractModule { // Create the required DirectoryResourceFactory implementation install(new FactoryModuleBuilder() + .implement( + new TypeLiteral>() {}, + ActiveConnectionDirectoryResource.class + ) .build(new TypeLiteral>() {})); // Create the required DirectoryObjectResourceFactory implementation diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/connection/ConnectionDirectoryResource.java b/guacamole/src/main/java/org/apache/guacamole/rest/connection/ConnectionDirectoryResource.java new file mode 100644 index 000000000..63bc87940 --- /dev/null +++ b/guacamole/src/main/java/org/apache/guacamole/rest/connection/ConnectionDirectoryResource.java @@ -0,0 +1,71 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.guacamole.rest.connection; + +import com.google.inject.assistedinject.Assisted; +import com.google.inject.assistedinject.AssistedInject; +import javax.ws.rs.Consumes; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; +import org.apache.guacamole.net.auth.Connection; +import org.apache.guacamole.net.auth.Directory; +import org.apache.guacamole.net.auth.UserContext; +import org.apache.guacamole.rest.directory.DirectoryObjectResourceFactory; +import org.apache.guacamole.rest.directory.DirectoryObjectTranslator; +import org.apache.guacamole.rest.directory.DirectoryResource; + +/** + * A REST resource which abstracts the operations available on a Directory of + * Connections. + * + * @author Michael Jumper + */ +@Produces(MediaType.APPLICATION_JSON) +@Consumes(MediaType.APPLICATION_JSON) +public class ConnectionDirectoryResource + extends DirectoryResource { + + /** + * Creates a new ConnectionDirectoryResource which exposes the operations + * and subresources available for the given Connection Directory. + * + * @param userContext + * The UserContext associated with the given Directory. + * + * @param directory + * The Directory being exposed. + * + * @param translator + * A DirectoryObjectTranslator implementation which handles + * Connections. + * + * @param resourceFactory + * A factory which can be used to create instances of resources + * representing Connections. + */ + @AssistedInject + public ConnectionDirectoryResource(@Assisted UserContext userContext, + @Assisted Directory directory, + DirectoryObjectTranslator translator, + DirectoryObjectResourceFactory resourceFactory) { + super(userContext, directory, translator, resourceFactory); + } + +} diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/connection/ConnectionModule.java b/guacamole/src/main/java/org/apache/guacamole/rest/connection/ConnectionModule.java index 9f716719f..228e53c3a 100644 --- a/guacamole/src/main/java/org/apache/guacamole/rest/connection/ConnectionModule.java +++ b/guacamole/src/main/java/org/apache/guacamole/rest/connection/ConnectionModule.java @@ -27,6 +27,7 @@ import com.google.inject.TypeLiteral; import com.google.inject.assistedinject.FactoryModuleBuilder; import org.apache.guacamole.net.auth.Connection; import org.apache.guacamole.rest.directory.DirectoryObjectTranslator; +import org.apache.guacamole.rest.directory.DirectoryResource; /** * Guice Module which configures injections required for handling Connection @@ -41,6 +42,10 @@ public class ConnectionModule extends AbstractModule { // Create the required DirectoryResourceFactory implementation install(new FactoryModuleBuilder() + .implement( + new TypeLiteral>() {}, + ConnectionDirectoryResource.class + ) .build(new TypeLiteral>() {})); // Create the required DirectoryObjectResourceFactory implementation diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/directory/DirectoryObjectResource.java b/guacamole/src/main/java/org/apache/guacamole/rest/directory/DirectoryObjectResource.java index 7e45b2b82..463a1a017 100644 --- a/guacamole/src/main/java/org/apache/guacamole/rest/directory/DirectoryObjectResource.java +++ b/guacamole/src/main/java/org/apache/guacamole/rest/directory/DirectoryObjectResource.java @@ -19,8 +19,6 @@ package org.apache.guacamole.rest.directory; -import com.google.inject.assistedinject.Assisted; -import com.google.inject.assistedinject.AssistedInject; import javax.ws.rs.Consumes; import javax.ws.rs.DELETE; import javax.ws.rs.GET; @@ -51,7 +49,7 @@ import org.apache.guacamole.net.auth.Identifiable; */ @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON) -public class DirectoryObjectResource { +public abstract class DirectoryObjectResource { /** * The Directory which contains the object represented by this @@ -84,9 +82,7 @@ public class DirectoryObjectResource directory, - @Assisted InternalType object, + public DirectoryObjectResource(Directory directory, InternalType object, DirectoryObjectTranslator translator) { this.directory = directory; this.object = object; diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/directory/DirectoryResource.java b/guacamole/src/main/java/org/apache/guacamole/rest/directory/DirectoryResource.java index 2dbf7f136..5f1e950cd 100644 --- a/guacamole/src/main/java/org/apache/guacamole/rest/directory/DirectoryResource.java +++ b/guacamole/src/main/java/org/apache/guacamole/rest/directory/DirectoryResource.java @@ -19,8 +19,6 @@ package org.apache.guacamole.rest.directory; -import com.google.inject.assistedinject.Assisted; -import com.google.inject.assistedinject.AssistedInject; import java.util.Collection; import java.util.HashMap; import java.util.List; @@ -69,7 +67,7 @@ import org.apache.guacamole.rest.PATCH; */ @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON) -public class DirectoryResource { +public abstract class DirectoryResource { /** * The UserContext associated with the Directory being exposed by this @@ -113,9 +111,7 @@ public class DirectoryResource * A factory which can be used to create instances of resources * representing individual objects contained within the given Directory. */ - @AssistedInject - public DirectoryResource(@Assisted UserContext userContext, - @Assisted Directory directory, + public DirectoryResource(UserContext userContext, Directory directory, DirectoryObjectTranslator translator, DirectoryObjectResourceFactory resourceFactory) { this.userContext = userContext;