We are migrating our application from spray to akka-http. We have a requirement to fetch few attributes from HttpServletRequest (set by filters).
Spray has a provision to extract HttpServletRequest by setting spray.servlet.servlet-request-access to on, like:
def httpServletRequest(requestContext: RequestContext): Option[HttpServletRequest] = {
requestContext.request.headers collect { case ServletRequestInfoHeader(hsRequest) => hsRequest } headOption
}
However, I couldn't find similar provision in akka-http. Is there a we can acheive this in akka-http?
Update:
As per AKKA-http deployment, spray-servlet is not yet ported to akka-http, and akka runs on embeded webserver. Where as our application runs on Tomcat, So we need to wait for sometime to use akka-http on tomcat.
spray-servlet is not yet ported to akka-http
Don't hold your breath. The Akka team didn't port over the spray-servlet module to Akka HTTP, because servlet containers don't fill well with the reactive approach to which Akka adheres.
Related
I can't find any example in scala/java where the server side is accessing the context of a grpc request (with scalapb / grpc.io). I can find many examples in golang. I found some of with akka grpc but I am using scalapb and grpc.io
If anyone knows of a repo in github that uses it or can layout the steps needs to access it, it would be very kind of you
In grpc-java and ScalaPB you get access to the request's metadata through client and server interceptors. See: https://grpc.github.io/grpc-java/javadoc/io/grpc/ServerInterceptor.html
Example: https://github.com/saturnism/grpc-java-by-example/tree/master/metadata-context-example/src/main/java/com/example/grpc/server
I am learning to use React at the moment, and I have a problem: I want react to work with my Java Spring Boot backend (Tomcat). React is running on port 3000 (default) and my Tomcat server on port 8080 (default). Now, when I make a REST call, I get the following error
script.js:13 GET http://localhost:8080/api/path?p=test net::ERR_CONNECTION_REFUSED
My rest call looks like:
fetch('http://localhost:8080/api/path?p=test')
.then(res => {
console.log(res);
});
What do I make wrong? I do not really have an idea.
An net::ERR_CONNECTION_REFUSED error is typically thrown when your frontend (React application) cannot connect to your backend (your Spring boot application). There are many possible reasons for this to happen, such as:
Your back-end application is not running
The path to your back-end application is not correct
There is some kind of firewall between your front- and back-end application that is stopping the traffic
...
In your case it appeared to be the back-end application that was not running properly.
Your second problem is related to CORS, which is a mechanism that prevents JavaScript from connecting to other APIs/websites that are not on the same (sub)domain and port. In your case your frontend is running on a different port than you backend, so that means you have to deal with CORS.
To handle CORS, you have to add a header to your backend (namely the Access-Contol-Allow-Origin header the error is mentioning). With Spring, you can do that by adding the following annotation to your controller:
#CrossOrigin(origins = "http://localhost:3000")
Or you can configure CORS globally with a filter or using WebMvcConfigurer:
#Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurerAdapter() {
#Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/api/**").allowedOrigins("http://localhost:3000");
}
};
}
As mentioned in the comments by #Lutz Horn, this is also described in a Spring guide.
Using Scala 2.10 and Akka 2.3.4, I've put together a simple proxy server that accepts incoming TCP connections and then proxies those messages to a remote server. Things are working with plain text, but I'm stuck with SSL.
Briefly, this is how I launch my non-secure server for incoming connections:
val server = system.actorOf(Props(new LegacyTCPServer), name = "my-tcp-server")
implicit val bindingTimeout = Timeout(1.second)
import system.dispatcher // execution context for the future
val boundFuture = IO(Tcp) ? Tcp.Bind(server, endpoint)
boundFuture.onSuccess { case Tcp.Bound(address) =>
println("Fantastic! We have a connection: " + address)
}
I can connect to this server via telnet, but now I'd like to move no to opensl. I guess there must be some configuration options for that, but I can't seem to parse it from the documentation: http://doc.akka.io/docs/akka/2.3.4/scala.html
I have seen some (non-functional) examples using akka 2.2.x that use a TCPPipelineHandler, e.g.,
https://groups.google.com/forum/#!topic/akka-user/auErrrk9wS0
https://github.com/betehess/ping-pong-bot/blob/master/app/ircbot/IrcClient.scala#L183
but TCPPipelineHandler doesn't seem to exist in akka 2.3.x, so that feels like a dead end.
I would love it if someone could provide an example of how to set up a tcp socket over ssl using current versions of Scala & Akka.
Please let me know if you'd like more information. Thanks!
spray is HTTP server/client built on top of Akka IO.
There is a pipelining infrastructure and SslTlsSupport in "io.spray" % "spray-io" % "1.3.1" package. I use it in a project, I'm currently working on. For more details, please see how it is configured for HttpServerConnection in spray.
You would need to refactor your code to use pipelines from spray, from my experience code becomes much easier if you split your code into multiple stages each responsible for a small piece.
Is there an built in HTTP server in Apache CXF like "HttpServerFactory" of Jersey?
I tried reading through the CXF documentation but couldn't find anything similar.
Yes, there is.
If you want JAX-RS service deployed on built-in server use org.apache.cxf.jaxrs.JAXRSServerFactoryBean. Example usage (taken from CXF samples):
JAXRSServerFactoryBean sf = new JAXRSServerFactoryBean();
sf.setResourceClasses(CustomerService.class);
sf.setResourceProvider(CustomerService.class,
new SingletonResourceProvider(new CustomerService()));
sf.setAddress("http://localhost:9000/");
sf.create();
If you want JAX-WS service deployed on built-in server you can use javax.xml.ws.Endpoint.publish(..). Sample code (again copied from CXF Sample):
HelloWorldImpl implementor = new HelloWorldImpl();
String address = "http://localhost:9000/helloWorld";
Endpoint.publish(address, implementor);
Both JAX-WS and JAX-RS require adding org.apache.cxf:cxf-rt-transports-http-jetty to classpath.
I really recommend taking look at CXF samples. Sometimes they are indispensable.
I want to write a thrift service implementation in Scala (using Scrooge) but without the use of Finagle, since I couldn't write a ruby/python client for Finagle servers. The problem is that with scrooge the service doesn't seem to implement "Processor" class.
Assume I have a thrift definition like this:
service TestService {
void testFunction(1: string message);
}
and I generated the scala files using scrooge, when I tried to use the standard implementation of thrift for scala with that to run the server:
val st = new TServerSocket(9999)
val processor = new TestService.Processor(new TestServiceImpl)
val arg = new TThreadPoolServer.Args(st)
arg.processor(processor)
val server = new TThreadPoolServer(arg)
server.serve()
The generated TestService object doesn't seem to have the Processor inner class. Any idea how to do that without Finagle? or as another solution, how to write a python or ruby client to finagle thrift servers?
You must use the finagle thrift implementation with Scrooge. Note that it is all wire and IDL compatible, so you can use whatever implementations you want, given that you share the IDL.
You can write Ruby or Python clients for the finagle thrift service: it speaks the same protocol.
Based on the project you linked to, it appears that you have a transport mismatch between client and server.
Your python client is using the buffered transport:
transport = TTransport.TBufferedTransport(transport)
But your scala server is using the framed transport:
.codec(ThriftServerFramedCodec())
If you change the python client to use the framed transport, your issue should go away:
transport = TTransport.TFramedTransport(transport)
My problem has been solved by using the same transport in both python and scala.
in my python client.
transport = TTransport.TFramedTransport(transport)
You can find the sample working link