-
Notifications
You must be signed in to change notification settings - Fork 551
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Problems with 403 Forbidden and 405 Method Not Allowed #17
Comments
Looking into it. Just to confirm, if you start this on your local machine using the embedded container in Jersey it responds correctly? Could you also share a Swagger file with your API Gateway configuration (or a screenshot of the console?) |
I've tried to test something similar in local with Jersey 2.24. Looks like you cannot define a method with a sub-path in the interface, you have to define both in the implementation. Note that all of these tests are with the embedded Grizzly container in local. We'll get to Lambda and API Gateway next. The DELETE method works for me when the interface is defined like this: public interface ContactResource
{
@DELETE // you could skip this, it's here just for clarity
@Consumes({MediaType.APPLICATION_JSON})
@Produces({MediaType.APPLICATION_JSON})
public Response deleteContact(String id);
@POST
@Consumes({MediaType.APPLICATION_JSON})
@Produces({MediaType.APPLICATION_JSON})
public Response createContact(Map<String, String> co);
} And the implementation looks like this @Path("contacts")
public class ContactResourceImpl implements ContactResource {
@DELETE
@Path("{id}")
public Response deleteContact(@PathParam("id") String id)
{
return Response.status(204).build();
}
public Response createContact(Map<String, String> co)
{
return Response.status(200).build();
}
} |
So when I define in both Interface and Implementation, I get Duplicate definition errors. It thinks both the Interface and Implementation are definitions. So I ran my JUnit tests, which I'm assuming fires up Grizzly. All tests worked. I've actually got more methods:
And it appears that all my tests work just fine. Thanks, |
Is there a repo where we can take a look at the entire app? When I initialize my code with the On the 1st question, 403 is normally returned by API Gateway when you try to open a method that is not defined in the API. Would be good to see the API Gateway definition. 405 on the other hand, it's definitely not API Gateway unless you have explicitly defined that as a response code. |
Thanks Daniel, You are getting a 403 on the POST because there isn't an HTTP method defined in the
This is a start. I'll look into the code today but the 405 sounds like something with Jersey. I'll let you know what I find. |
Oh wow! I didn't know you had to do that! Thanks so much! That helps a lot. I'll try that out very shortly. David |
I also edited your comment to add an even more scrubbed version of the impl class. |
Assuming the API Gateway configuration fixes your 403 on the POST. I'm now trying to replicate the 405 on the DELETE method without much luck. When I start the server in local with your latest code, it responds to the DELETE method as expected. Same when I use Lambda and API Gateway. This is the class I'm using to run the local tests: import org.glassfish.grizzly.http.server.HttpServer;
import org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpServerFactory;
import org.glassfish.jersey.jackson.JacksonFeature;
import org.glassfish.jersey.logging.LoggingFeature;
import org.glassfish.jersey.server.ResourceConfig;
import javax.ws.rs.core.UriBuilder;
import java.io.IOException;
import java.net.InetAddress;
import java.net.URI;
import java.net.UnknownHostException;
public class Service {
public static void main(String[] args) throws IOException {
System.out.println("Starting Embedded Jersey HTTPServer...\n");
HttpServer httpServer = createHttpServer();
httpServer.start();
}
private static HttpServer createHttpServer() throws IOException {
ResourceConfig rc = new ResourceConfig()
.packages("com.sapessi.testapi") // this is the package where I created your Contact class
.register(JacksonFeature.class)
.register(LoggingFeature.class);
return GrizzlyHttpServerFactory.createHttpServer(getServerUri(), rc);
}
private static URI getServerUri() {
return UriBuilder.fromUri("http://" + getLocalHostname() + "/").port(8085).build();
}
private static String getLocalHostname() {
String hostName = "localhost";
try {
hostName = InetAddress.getLocalHost().getCanonicalHostName();
} catch (UnknownHostException e) {
e.printStackTrace();
}
return hostName;
}
} And this is my simple Lambda handler: import com.amazonaws.serverless.proxy.internal.model.AwsProxyRequest;
import com.amazonaws.serverless.proxy.internal.model.AwsProxyResponse;
import com.amazonaws.serverless.proxy.jersey.JerseyLambdaContainerHandler;
import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;
import org.glassfish.jersey.jackson.JacksonFeature;
import org.glassfish.jersey.server.ResourceConfig;
public class LambdaHandler implements RequestHandler<AwsProxyRequest, AwsProxyResponse> {
private ResourceConfig jerseyApplication = new ResourceConfig()
.packages("com.sapessi.testapi")
.register(JacksonFeature.class);
private JerseyLambdaContainerHandler<AwsProxyRequest, AwsProxyResponse> handler
= JerseyLambdaContainerHandler.getAwsProxyHandler(jerseyApplication);
public AwsProxyResponse handleRequest(AwsProxyRequest awsProxyRequest, Context context) {
return handler.proxy(awsProxyRequest, context);
}
} |
So adding the additional method under the /contacts resource made everything work! Not sure I totally understand why, but as long as it works, I'm happy. I'd also be interested in contributing to this project if you are looking for developers/maintainers. Let me know. Thanks, |
Thanks David, I'm currently working on issues #15 and #16. However, if there are other features you need in the library, feel free to open a new issue and send a pull request. We are always looking for feedback on the library. I'm going to close this issue for now. thanks for all the help to debug this. |
Hi,
I'm having an issue trying to get a single Java Lambda to handle all HTTP Methods.
Here's my interface:
And my implementation class:
Yet when I try to use Postman to call POST on /contacts (actually /TEST/contacts because TEST is my stage name), I get the 403 Forbidden error.
And when I try to use DELETE on /contacts/12345 - where I should receive a 404 Not Found because Contact with id 12345 doesn't exist - I get 405 Method Not Allowed. I also get a return header of "Allow={GET,OPTIONS,PUT}".
Any help would be greatly appreciated!
Thanks,
David
The text was updated successfully, but these errors were encountered: