I'm trying to use websocket using openshift and wildfly 8.1.
The application works on a local wildfly server on port 8080.
But, I'm not able to connect on openshift server for the websocket using port 8000.
Curriously, if I use port forwarding (rhc port-forward), I'm able to connect on the local forwarded port.
I think there is a missconfiguration for port forwarding on openshift.
Here is my code :
import javax.websocket.EncodeException;
import javax.websocket.CloseReason;
import javax.websocket.EndpointConfig;
import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.OnError;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;
#ServerEndpoint("/ws/websocket")
public class WebSocketService{
#OnOpen
public void onOpen(Session peer, EndpointConfig config) {
System.err.println("Open");
peer.getAsyncRemote().sendText("Hello");
}
#OnClose
public void onClose(Session peer, CloseReason reason) {
System.err.println("Close");
}
#OnError
public void onError(Session peer, Throwable throwable) {
System.err.println("Error");
}
}
WildFly port on OpenShift should be 8080, not 8000 as you mentioned.
Are you able to connect to localhost:8080 and redirected to your OpenShift instance ?
Does Chrome Developer Tools show any errors ?
Related
I am trying to migrate my REST client application to use WebClient instead of RestTemplate.
But, when I run my client code, it is apparently trying to start a web server and connect to port 8080, which fails because Tomcat is already running on the port.
I don't want to start a web server. I just want to connect to an external web server and pull back a response.
Here is the error I get:
***************************
APPLICATION FAILED TO START
***************************
Description:
Web server failed to start. Port 8080 was already in use.
Action:
Identify and stop the process that's listening on port 8080 or configure this application to listen on another port.
Here is my test code:
package test.rest.webClient;
import java.util.Map;
import org.apache.hc.core5.net.URIBuilder;
import org.slf4j.LoggerFactory;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.MediaType;
import org.springframework.web.reactive.function.client.WebClient;
import org.springframework.web.reactive.function.client.WebClient.RequestHeadersUriSpec;
import org.springframework.web.reactive.function.client.WebClient.ResponseSpec;
import reactor.core.publisher.Mono;
import test.Path;
#SpringBootApplication
public class WebClientTest implements CommandLineRunner {
#Override
public void run(String... args)
throws Exception {
URIBuilder builder = new URIBuilder();
builder.setScheme("https");
builder.setHost("marketing.propfinancing.com");
builder.setPath("/caddata/TXCollin/getByIdAndYear");
builder.addParameter("id", "37");
builder.addParameter("year", "2022");
WebClient client = WebClient.create();
RequestHeadersUriSpec<?> uriSpec = client.get();
uriSpec.uri(builder.build());
uriSpec.header(Path.getApplicationProperties().getProperty("caddata.apiKey.header.name"),
Path.getApplicationProperties().getProperty("caddata.apiKey"));
uriSpec.accept(MediaType.APPLICATION_JSON);
ResponseSpec responseSpec = uriSpec.retrieve();
ParameterizedTypeReference<Map<String,Object>> typeReference = new ParameterizedTypeReference<Map<String,Object>>(){};
Mono<Map<String,Object>> mono = responseSpec.bodyToMono(typeReference);
Map<String,Object> response = mono.block();
for( Object key : response.keySet() ) {
Object value = response.get(key);
LoggerFactory.getLogger(getClass()).warn(key+":"+value);
}
}
public static void main(String[] args)
throws Exception {
SpringApplication.run(WebClientTest.class, args);
}
}
Any ideas?
Per default spring boot starts up either as a web application or a reactive application depending on what libraries you have on your classpath.
But you can also tell the framwork to not start up the webserver by explicitly setting the WebApplicationType to None
here is an example:
new SpringApplicationBuilder(MainApplication.class)
.web(WebApplicationType.NONE)
.run(args);
or you can set it in the application properties:
spring.main.web-application-type=none
You can read more about it here:
17.1.5. Create a Non-web Application
Spring Boot no web server
I am using trying to setup project with Consul. I can start my SpringBoot with Consul running. But how can I do test in Maven build? The build server does not have Consul install and running
package com.example.demo2;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.consul.discovery.ConsulDiscoveryClient;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT;
#SpringBootTest
class Demo2ApplicationTests {
#Autowired
private ConsulDiscoveryClient discoveryClient;
#Test
void contextLoads() {
}
#Test
public void testClient() {
List<ServiceInstance> instances = this.discoveryClient.getInstances("testConsulDiscovery");
assertThat(instances).as("instances was null").isNotNull();
assertThat(instances.isEmpty()).as("instances was empty").isFalse();
ServiceInstance instance = instances.get(0);
assertThat(instance.isSecure()).as("instance was secure (https)").isFalse();
assertIpAddress(instance);
assertThat(instance.getMetadata()).containsEntry("foo", "bar");
}
}
The following error was received
com.ecwid.consul.transport.TransportException: org.apache.http.conn.HttpHostConnectException: Connect to localhost:8500 [localhost/127.0.0.1, localhost/0:0:0:0:0:0:0:1] failed: Connection refused: no further information
I am working on a Spring Boot Server Project which offered simple REST resources until now. In order to push notifications to the client I want to add a websocket connection. To test this connection I have written a Integration Test using a SockJS Client based on this tutorial :
http://rafaelhz.github.io/testing-websockets/
Problem is that the Connection is refused with the following error:
org.springframework.web.client.ResourceAccessException: I/O error on GET request for "http://localhost:9090/websocket/info": Connection refused (Connection refused); nested exception is java.net.ConnectException: Connection refused (Connection refused)
My Websocket Configuration is as follows:
import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.web.socket.config.annotation.AbstractWebSocketMessageBrokerConfigurer;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
#Configuration
#EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {
#Override
public void configureMessageBroker(MessageBrokerRegistry config) {
config.enableSimpleBroker("/topic");
config.setApplicationDestinationPrefixes("/app");
}
#Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry
.addEndpoint("/websocket")
.setAllowedOrigins("*")
.withSockJS();
}
}
I can see in the that the socket endpoint is mapped int the log:
2017-07-14 15:22:59.561 INFO 13765 --- [ main] o.s.w.s.s.s.WebSocketHandlerMapping : Mapped URL path [/websocket/**] onto handler of type [class org.springframework.web.socket.sockjs.support.SockJsHttpRequestHandler]
The Server Port is set to 9090 in the application.yml file:
server:
port: 9090
The following unit test is not able to connect to the socket:
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.web.socket.client.standard.StandardWebSocketClient;
import org.springframework.web.socket.messaging.WebSocketStompClient;
import org.springframework.web.socket.sockjs.client.SockJsClient;
import org.springframework.web.socket.sockjs.client.WebSocketTransport;
import org.springframework.messaging.simp.stomp.StompFrameHandler;
import org.springframework.messaging.simp.stomp.StompHeaders;
import org.springframework.messaging.simp.stomp.StompSession;
import org.springframework.messaging.simp.stomp.StompSessionHandlerAdapter;
import java.lang.reflect.Type;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingDeque;
import static java.util.Arrays.asList;
import static java.util.concurrent.TimeUnit.SECONDS;
#RunWith(SpringRunner.class)
#SpringBootTest
#ActiveProfiles("test")
//#DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
public class WebSocketConnectionTest {
static final String WEBSOCKET_URI = "ws://localhost:9090/websocket";
static final String WEBSOCKET_TOPIC = "/topic";
BlockingQueue<String> blockingQueue;
WebSocketStompClient stompClient;
#Before
public void setup() {
blockingQueue = new LinkedBlockingDeque<>();
stompClient = new WebSocketStompClient(new SockJsClient(
asList(new WebSocketTransport(new StandardWebSocketClient()))));
System.out.println(WEBSOCKET_URI);
}
#Test
public void shouldReceiveAMessageFromTheServer() throws Exception {
StompSession session = stompClient
.connect(WEBSOCKET_URI, new StompSessionHandlerAdapter() {})
.get(1, SECONDS);
session.subscribe(WEBSOCKET_TOPIC, new DefaultStompFrameHandler());
String message = "MESSAGE TEST";
session.send(WEBSOCKET_TOPIC, message.getBytes());
Assert.assertEquals(message, blockingQueue.poll(1, SECONDS));
}
class DefaultStompFrameHandler implements StompFrameHandler {
#Override
public Type getPayloadType(StompHeaders stompHeaders) {
return byte[].class;
}
#Override
public void handleFrame(StompHeaders stompHeaders, Object o) {
blockingQueue.offer(new String((byte[]) o));
}
}
}
The connection is refused. Im fairly certain that this happens because the URI endpoint does not exist, but I don't know why. Does somebody know if there is a error in the URI or if something else leads to the refused connection ?
I found out the cause of the problem. The endpoint did not exist on PORT 9090. That is because the #SpringBootTest Annotation sets the WebEnvironment to WebEnvironment.MOCK by default. In this configuration No Embedded Servlet is started and therefor and no port exists, only MockMvc-based testing is possible. In order to start an Embedded servlet
the Environment has to be set to WebEnvironment.RANDOM_PORT or WebEnvironment.DEFINED_PORT. I set it to DEFINED_PORT so that the port 9090 from my application.yml is used. By Setting the Environment the test runs correctly.
#RunWith(SpringRunner.class)
#SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)//!!!!!
#ActiveProfiles("test")
#DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
public class WebSocketConnectionTest {
String WEBSOCKET_URI = "ws://localhost:9090/websocket";
String WEBSOCKET_TOPIC = "/topic";
.
.
.
I'm running a Spring boot (Jhipster/Undertow) application on port 8080 on an AWS EC2 instance.
I have an AWS ELB configured to redirect
80 -> 8080
443 (SSL termination happens here) -> 8080
The application uses Spring Security and if you user arrives to http://example.com I want it to redirect to https://example.com, to use SSL.
I have found various examples of configuring this in Tomcat but none using Undertow.
I have tried this, with a second port 8089, and it does redirect as required, but this causes port 8080 to also redirects which I don't want.
80 -> 8089
443 (SSL termination happens here) -> 8080
#Bean
public EmbeddedServletContainerFactory undertow() {
UndertowEmbeddedServletContainerFactory undertow = new UndertowEmbeddedServletContainerFactory();
undertow.addBuilderCustomizers(builder -> builder.addHttpListener(8089, "0.0.0.0"));
undertow.addDeploymentInfoCustomizers(deploymentInfo -> {
deploymentInfo.addSecurityConstraint(new SecurityConstraint()
.addWebResourceCollection(new WebResourceCollection()
.addUrlPattern("/*"))
.setTransportGuaranteeType(TransportGuaranteeType.CONFIDENTIAL)
.setEmptyRoleSemantic(SecurityInfo.EmptyRoleSemantic.PERMIT))
.setConfidentialPortManager(exchange -> 443);
});
return undertow;
}
How can I configure Undertow to achieve this?
This worked for me when I had the same problem:
Expose the port 80 from jhipster (you can change it in the application-prod.yml).
Amazon ELB when redirecting from http to https adds some headers, which you should address in the same file:
server:
use-forward-headers: true
port: 80
Also, you need to enforce the https from jhipster:
https://jhipster.github.io/tips/007_tips_enforce_https.html
Just in case if somebody wants a working solution for redirecting all http requests to https with HTTP/2 in Spring Boot 1.5.19, following is the setting in application.properties file:
server.ssl.protocol=TLSv1.2
server.ssl.key-store-type=PKCS12
server.ssl.key-store=keystore.p12
server.ssl.key-store-password=xxxxxxx
server.port=443
server.use-forward-headers=true
And the following Java configuration:
import io.undertow.UndertowOptions;
import io.undertow.servlet.api.SecurityConstraint;
import io.undertow.servlet.api.SecurityInfo;
import io.undertow.servlet.api.TransportGuaranteeType;
import io.undertow.servlet.api.WebResourceCollection;
import org.springframework.boot.context.embedded.undertow.UndertowBuilderCustomizer;
import org.springframework.boot.context.embedded.undertow.UndertowEmbeddedServletContainerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
#Configuration
public class ConnectorConfig {
#Bean
public UndertowEmbeddedServletContainerFactory embeddedServletContainerFactory() {
UndertowEmbeddedServletContainerFactory factory = new UndertowEmbeddedServletContainerFactory();
factory.addBuilderCustomizers((UndertowBuilderCustomizer) builder -> {
builder.setServerOption(UndertowOptions.ENABLE_HTTP2, true);
builder.addHttpListener(80, "0.0.0.0");
});
factory.addDeploymentInfoCustomizers(deploymentInfo -> {
deploymentInfo.addSecurityConstraint(
new SecurityConstraint()
.addWebResourceCollection(new WebResourceCollection().addUrlPattern("/*"))
.setTransportGuaranteeType(TransportGuaranteeType.CONFIDENTIAL)
.setEmptyRoleSemantic(SecurityInfo.EmptyRoleSemantic.PERMIT))
.setConfidentialPortManager(exchange -> 443);
});
return factory;
}
}
Everything will be working perfectly.
I had created a Proxy Server (Fwd and Reverse) using Java sockets.
which would listen to Incoming Request on 8080 configured in browser and forward them to another Proxy Server2.
And Read the Response sent by the server2 and write it to the browser.
Meanwhile code will be logging requests and response and also blocking certain predefined request types from browser.
Now I want to do this using Jetty and also support HTTPS request.
I searched for example but I found none.
This starts server at 8080 which I have configured as proxy port in Browser's proxy setting.
import org.eclipse.jetty.server.Server;
import Handler.HelloHandler;
public class StartJetty
{
public static void main(String[] args) throws Exception
{
Server server = new Server(8080);
server.setHandler(new HelloHandler());
server.start();
server.join();
}
}
This is the handler which I use to listen to request and write response back to browser.
package Handler;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.handler.AbstractHandler;
public class HelloHandler extends AbstractHandler
{
final String _greeting;
final String _body;
public HelloHandler()
{
_greeting="Hello World";
_body=null;
}
public HelloHandler(String greeting)
{
_greeting=greeting;
_body=null;
}
public HelloHandler(String greeting,String body)
{
_greeting=greeting;
_body=body;
}
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
{
response.setContentType("text/html;charset=utf-8");
response.setStatus(HttpServletResponse.SC_OK);
baseRequest.setHandled(true);
response.getWriter().println("<h1>"+_greeting+"</h1>");
if (_body!=null)
response.getWriter().println(_body);
}
}
Once I have the response I want to forward it to proxy server, wait for its response and write it back to the Browser. I need help with that.
In the jetty-servlets artifact there is a ProxyServlet that will do async proxy work for you.
I would just give that a try and see if it fits your needs.
In the tests of that project is an AsyncProxyServer that you can just start up and give a whirl.
The underlying continuation and jetty clients used for the proxying are extensible through the customize methods.
http://git.eclipse.org/c/jetty/org.eclipse.jetty.project.git/tree/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/ProxyServlet.java?h=jetty-8
and
http://git.eclipse.org/c/jetty/org.eclipse.jetty.project.git/tree/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/AsyncProxyServer.java?h=jetty-8
good luck