OpenShift: Cannot Connect to WebSocket with Alias (bug) - websocket

I have a Java Spring Web application which uses WebSockets. An HTML file connects to the WebSocket using the uri:
var wsUri = "wss://" + document.location.hostname + ":8443" + "/serverendpoint";
Here is my serverendpoint.java code that creates the WebSocket:
package com.myapp.spring.web.controller;
import java.io.IOException;
import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;
import org.springframework.web.socket.server.standard.SpringConfigurator;
#ServerEndpoint(value="/serverendpoint", configurator = SpringConfigurator.class)
public class serverendpoint {
#OnOpen
public void handleOpen () {
System.out.println("JAVA: Client is now connected...");
}
#OnMessage
public String handleMessage (Session session, String message) throws IOException {
if (message.equals("ping")) {
// return "pong"
session.getBasicRemote().sendText("pong");
}
else if (message.equals("close")) {
handleClose();
return null;
}
System.out.println("JAVA: Received from client: "+ message);
MyClass mc = new MyClass(message);
String res = mc.action();
session.getBasicRemote().sendText(res);
return res;
}
#OnClose
public void handleClose() {
System.out.println("JAVA: Client is now disconnected...");
}
#OnError
public void handleError (Throwable t) {
t.printStackTrace();
}
}
When I connect to the websocket using the http://myapp-myproject.rhcloud.com/mt URL, the WebSocket connects. However, when I set up an alias to the http://myapp-myproject.rhcloud.com, which is called https://someurl.com/mt, the websocket doesn't connect. Why is this? I get the following error message in Google Chrome:
Furthermore, the websocket uses a wss connection at port 8443. This is a secure request equivalent to https. Therefore, how can it work with the http://myapp-myproject.rhcloud.com/mt URL which is an http URL, and why is it not connecting with the alias?
Thank you so much for your help!

Related

Client extract SSL/TLS certificate from a reactor-netty connection

java.net has a simple getServerCertificates in its API (example follows). I was looking for a similar operation in reactor-netty, and if not there, in any other reactive API for spring-boot/webflux/HttpClient.
This operation (client reads certificate) does not seem possible in reactor-netty. Is it? If it isn't is there an alternative method in another spring-boot component to do this?
package com.example.readCertificate.service;
import java.net.URL;
import java.securiiity.cert.Certificate;
import javax.net.ssl.HttpsURLConnection;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class ShowCert {
private Logger logger = LogManager.getLogger();
public void showCert(String url) {
try {
URL destinationURL = new URL(url);
HttpsURLConnection connection = (HttpsURLConnection) destinationURL.openConnection();
connection.connect();
Certificate[] certificates = connection.getServerCertificates();
for (Certificate certificate : certificates) {
logger.info("certificate is:" + certificate);
}
} catch (Exception e) {
logger.error(e);
}
}
}
In WebClient from Spring WebFlux we usually use netty as backend. We provide a bean ReactorClientHttpConnector in which we create netty http-client.
For handling SSL netty uses handler within the channel pipeline.
Here I'm putting a callback to event doOnConnected() and accesing the SSL handler and SSLSession.
SSLSession provides methods getPeerCertificates(), getLocalCertificates()
, so we can get access to certificates here.
#Bean
public ReactorClientHttpConnector reactorClientHttpConnector() {
return new ReactorClientHttpConnector(
HttpClient.create()
.doOnConnected(connection -> {
ChannelPipeline pipeline = connection.channel().pipeline();
Optional.ofNullable(pipeline)
.map(p -> p.get(SslHandler.class))
.map(SslHandler::engine)
.map(SSLEngine::getSession)
.ifPresent(sslSession -> {
try {
Certificate[] peerCertificates = sslSession.getPeerCertificates();
if (Objects.nonNull(peerCertificates)) {
Stream.of(peerCertificates)
.forEach(System.out::println);
}
} catch (Exception e) {
e.printStackTrace();
}
});
})
);
}
And create your WebClient:
#Bean
public WebClient httpsClient() {
return WebClient.builder()
.clientConnector(reactorClientHttpConnector())
.baseUrl("https://secured-resource.com)
.build();
}
Then while making http-call with this httpsClient bean you should see the results in your console

calling blocking feign client from reactive spring service

I am trying to call generated feign client from reactive spring flux like this:
.doOnNext(user1 -> {
ResponseEntity<Void> response = recorderClient.createUserProfile(new UserProfileDto().principal(user1.getLogin()));
if (!response.getStatusCode().equals(HttpStatus.OK)) {
log.error("recorder backend could not create user profile for user: {} ", user1.getLogin());
throw new RuntimeException("recorder backend could not create user profile for login name" + user1.getLogin());
}
})
Call is executed, but when I try to retrieve jwt token from reactive security context ( in a requets interceptor ) like this:
public static Mono<String> getCurrentUserJWT() {
return ReactiveSecurityContextHolder
.getContext()
.map(SecurityContext::getAuthentication)
.filter(authentication -> authentication.getCredentials() instanceof String)
.map(authentication -> (String) authentication.getCredentials());
}
....
SecurityUtils.getCurrentUserJWT().blockOptional().ifPresent(s -> template.header(AUTHORIZATION_HEADER, String.format("%s %s", BEARER, s)));
context is empty. As I am pretty new to reactive spring I am surely mussing something stupid and important.
Not sure how is your interceptor configured,
but in my case, i just simply implement ReactiveHttpRequestInterceptor and override apply() function
import feign.RequestInterceptor;
import feign.RequestTemplate;
import org.springframework.stereotype.Component;
import reactivefeign.client.ReactiveHttpRequest;
import reactivefeign.client.ReactiveHttpRequestInterceptor;
import reactor.core.publisher.Mono;
import java.util.Collections;
#Component
public class UserFeignClientInterceptor implements ReactiveHttpRequestInterceptor {
private static final String AUTHORIZATION_HEADER = "Authorization";
private static final String BEARER = "Bearer";
#Override
public Mono<ReactiveHttpRequest> apply(ReactiveHttpRequest reactiveHttpRequest) {
return SecurityUtils.getCurrentUserJWT()
.flatMap(s -> {
reactiveHttpRequest.headers().put(AUTHORIZATION_HEADER, Collections.singletonList(String.format("%s %s", BEARER, s)));
return Mono.just(reactiveHttpRequest);
});
}
}

Spring-Integration: Tcp Server Response not sent on Exception

I migrated a legacy tcp server code into spring-boot and added spring-intergration (annotation based) dependencies to handle tcp socket connections.
My inbound Channel is tcpIn() , outbound Channel is serviceChannel() and i have created a custom Channel [ exceptionEventChannel() ] to hold exception event messages.
I have a custom serializer/Deserialier method (ByteArrayLengthPrefixSerializer() extends AbstractPooledBufferByteArraySerializer), and a MessageHandler #ServiceActivator method to send response back to tcp client.
//SpringBoot 2.0.3.RELEASE, Spring Integration 5.0.6.RELEASE
package com.test.config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.event.EventListener;
import org.springframework.integration.annotation.IntegrationComponentScan;
import org.springframework.integration.annotation.ServiceActivator;
import org.springframework.integration.annotation.Transformer;
import org.springframework.integration.channel.DirectChannel;
import org.springframework.integration.event.inbound.ApplicationEventListeningMessageProducer;
import org.springframework.integration.ip.IpHeaders;
import org.springframework.integration.ip.tcp.TcpReceivingChannelAdapter;
import org.springframework.integration.ip.tcp.TcpSendingMessageHandler;
import org.springframework.integration.ip.tcp.connection.*;
import org.springframework.integration.ip.tcp.serializer.TcpDeserializationExceptionEvent;
import org.springframework.integration.router.ErrorMessageExceptionTypeRouter;
import org.springframework.integration.support.MessageBuilder;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.MessageHandlingException;
import org.springframework.messaging.MessagingException;
import java.io.IOException;
#Configuration
#IntegrationComponentScan
public class TcpConfiguration {
#SuppressWarnings("unused")
#Value("${tcp.connection.port}")
private int tcpPort;
#Bean
TcpConnectionEventListener customerTcpListener() {
return new TcpConnectionEventListener();
}
#Bean
public MessageChannel tcpIn() {
return new DirectChannel();
}
#Bean
public MessageChannel serviceChannel() {
return new DirectChannel();
}
#ConditionalOnMissingBean(name = "errorChannel")
#Bean
public MessageChannel errorChannel() {
return new DirectChannel();
}
#Bean
public MessageChannel exceptionEventChannel() {
return new DirectChannel();
}
#Bean
public ByteArrayLengthPrefixSerializer byteArrayLengthPrefixSerializer() {
ByteArrayLengthPrefixSerializer byteArrayLengthPrefixSerializer = new ByteArrayLengthPrefixSerializer();
byteArrayLengthPrefixSerializer.setMaxMessageSize(98304); //max allowed size set to 96kb
return byteArrayLengthPrefixSerializer;
}
#Bean
public AbstractServerConnectionFactory tcpNetServerConnectionFactory() {
TcpNetServerConnectionFactory tcpServerCf = new TcpNetServerConnectionFactory(tcpPort);
tcpServerCf.setSerializer(byteArrayLengthPrefixSerializer());
tcpServerCf.setDeserializer(byteArrayLengthPrefixSerializer());
return tcpServerCf;
}
#Bean
public TcpReceivingChannelAdapter tcpReceivingChannelAdapter() {
TcpReceivingChannelAdapter adapter = new TcpReceivingChannelAdapter();
adapter.setConnectionFactory(tcpNetServerConnectionFactory());
adapter.setOutputChannel(tcpIn());
adapter.setErrorChannel(exceptionEventChannel());
return adapter;
}
#ServiceActivator(inputChannel = "exceptionEventChannel", outputChannel = "serviceChannel")
public String handle(Message<MessagingException> msg) {
//String unfilteredMessage = new String(byteMessage, StandardCharsets.US_ASCII);
System.out.println("-----------------EXCEPTION ==> " + msg);
return msg.toString();
}
#Transformer(inputChannel = "errorChannel", outputChannel = "serviceChannel")
public String transformer(String msg) {
//String unfilteredMessage = new String(byteMessage, StandardCharsets.US_ASCII);
System.out.println("-----------------ERROR ==> " + msg);
return msg.toString();
}
#ServiceActivator(inputChannel = "serviceChannel")
#Bean
public TcpSendingMessageHandler out(AbstractServerConnectionFactory cf) {
TcpSendingMessageHandler tcpSendingMessageHandler = new TcpSendingMessageHandler();
tcpSendingMessageHandler.setConnectionFactory(cf);
return tcpSendingMessageHandler;
}
#Bean
public ApplicationListener<TcpDeserializationExceptionEvent> listener() {
return new ApplicationListener<TcpDeserializationExceptionEvent>() {
#Override
public void onApplicationEvent(TcpDeserializationExceptionEvent tcpDeserializationExceptionEvent) {
exceptionEventChannel().send(MessageBuilder.withPayload(tcpDeserializationExceptionEvent.getCause())
.build());
}
};
}
}
Messages in tcpIn() is sent to a #ServiceActivator method inside a separate #Component Class, which is structured like so :
#Component
public class TcpServiceActivator {
#Autowired
public TcpServiceActivator() {
}
#ServiceActivator(inputChannel = "tcpIn", outputChannel = "serviceChannel")
public String service(byte[] byteMessage) {
// Business Logic returns String Ack Response
}
I don't have issues running a success scenario. My Tcp TestClient gets Ack response as expected.
However, when i try to simulate an exception, say Deserializer Exception, The exception message is not sent back as a response to Tcp Client.
I can see my Application Listener getting TcpDeserializationExceptionEvent and sending the message to exceptionEventChannel. The #ServiceActivator method handle(Message msg) also prints my exception message. But it never reaches the breakpoints (in a debug mode) inside MessageHandler method out(AbstractServerConnectionFactory cf).
I am struggling to understand whats going wrong. Thanks for any help in advance.
UPDATE : I notice that the Socket is closed due to exception before the response can be sent. I'm trying to figure out a way around this
SOLUTION UPDATE (12th Mar 2019) :
Courtesy of Gary, i edited my deserializer to return a message that can be traced by a #Router method and redirected to errorChannel. The ServiceActivator listening to errorchannel then sends the desired error message to outputChannel . This solution seems to work.
My deserializer method inside ByteArrayLengthPrefixSerializer returning a "special value" as Gary recommended, instead of the original inputStream message.
public byte[] doDeserialize(InputStream inputStream, byte[] buffer) throws IOException {
boolean isValidMessage = false;
try {
int messageLength = this.readPrefix(inputStream);
if (messageLength > 0 && fillUntilMaxDeterminedSize(inputStream, buffer, messageLength)) {
return this.copyToSizedArray(buffer, messageLength);
}
return EventType.MSG_INVALID.getName().getBytes();
} catch (SoftEndOfStreamException eose) {
return EventType.MSG_INVALID.getName().getBytes();
}
}
I also made a few new channels to accommodate my Router such that the flow is as follows :
Success flow
tcpIn (#Router) -> serviceChannel(#serviceActivator that holds business logic) -> outputChannel (#serviceActivator that sends response to client)
Exception flow
tcpIn (#Router) -> errorChannel(#serviceActivator that prepares the error Response message) -> outputChannel (#serviceActivator that sends response to client)
My #Router and 'errorHandling' #serviceActivator -
#Router(inputChannel = "tcpIn", defaultOutputChannel = "errorChannel")
public String messageRouter(byte[] byteMessage) {
String unfilteredMessage = new String(byteMessage, StandardCharsets.US_ASCII);
System.out.println("------------------> "+unfilteredMessage);
if (Arrays.equals(EventType.MSG_INVALID.getName().getBytes(), byteMessage)) {
return "errorChannel";
}
return "serviceChannel";
}
#ServiceActivator(inputChannel = "errorChannel", outputChannel = "outputChannel")
public String errorHandler(byte[] byteMessage) {
return Message.ACK_RETRY;
}
The error channel is for handling exceptions that occur while processing a message. Deserialization errors occur before a message is created (the deserializer decodes the payload for the message).
Deserialization exceptions are fatal and, as you have observed, the socket is closed.
One option would be to catch the exception in the deserializer and return a "special" value that indicates a deserialization exception occurred, then check for that value in your main flow.

Netty ProxyHandler writeAndFlush is not writing response to server

Am trying to implement an NTLMProxyHandler in Netty that can perform the NTLM message exchanges and authenticate the client with a web proxy.
The NTLMProxyHandler extends Netty's ProxyHandler class. Due to this an initial HTTP request is triggered by the proxy handler and this reaches the mock proxy server that I have created. The proxy server reads this request and responds with a 407 proxy authentication required response.
The NTLMProxyHandler reads this response on the client side and prepares a new NTLM Type1Message and writes the response to server back again. The problem I am facing is that this request is never sent to my proxy server though the channel future's success handler is called.
I have enabled Netty packages in the logging but unable to figure out why only the response written second time from the ntlm proxy handler is lost.
I have tried using the Netty ProxyHandler's sendToProxyServer(msg) as well as using the channelHandlerCtx passed from channelRead(). In both the cases writeAndFlush is done but the response never reaches the server and the server times out.
Has anyone used the channelHandlerCtx to write back a response to the server and perform a message exchange similar to this ?
Why is the initial request from ntlm proxy handler -> server successful but not successive reponses written from this ntlm proxy handler.
I also see while debugging that even if I shutdown the proxy server while writing the NTLMMessage1, the writeAndFlush future is still successful. Why would the writeAndFlush succeed in this case ?
Any pointers will be really helpful. Thanks !
NTLMProxyHandler.java
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelPipeline;
import io.netty.handler.codec.http.DefaultFullHttpRequest;
import io.netty.handler.codec.http.DefaultFullHttpResponse;
import io.netty.handler.codec.http.FullHttpResponse;
import io.netty.handler.codec.http.HttpClientCodec;
import io.netty.handler.codec.http.HttpContent;
import io.netty.handler.codec.http.HttpHeaderNames;
import io.netty.handler.codec.http.HttpHeaders;
import io.netty.handler.codec.http.HttpMethod;
import io.netty.handler.codec.http.HttpResponse;
import io.netty.handler.codec.http.HttpResponseStatus;
import io.netty.handler.codec.http.HttpVersion;
import io.netty.handler.codec.http.LastHttpContent;
import io.netty.handler.proxy.ProxyConnectException;
import jcifs.ntlmssp.Type1Message;
import jcifs.ntlmssp.Type2Message;
import jcifs.ntlmssp.Type3Message;
import jcifs.smb.NtlmContext;
import jcifs.smb.NtlmPasswordAuthentication;
import jcifs.util.Base64;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
public class NTLMProxyHandler extends AbstractProxyHandler {
private String userName;
private String password;
private final static String DOMAIN = "CORP";
public static final String NTLM_Prefix = "NTLM";
private static final Logger logger = LoggerFactory.getLogger(NTLMProxyHandler.class);
private static int NTLMV2_FLAGS_TYPE3 = 0xa2888205;
private HttpResponseStatus status;
private HttpResponse response;
private NtlmPasswordAuthentication ntlmPasswordAuthentication;
private NtlmContext ntlmContext;
private final HttpClientCodec codec = new HttpClientCodec();
public NTLMProxyHandler(SocketAddress proxyAddress) {
super(proxyAddress);
}
public NTLMProxyHandler(SocketAddress proxyAddress, String domain, String username, String password) {
super(proxyAddress);
setConnectTimeoutMillis(50000);
this.userName = username;
this.password = password;
ntlmPasswordAuthentication = new NtlmPasswordAuthentication(DOMAIN, username, password);
ntlmContext = new NtlmContext(ntlmPasswordAuthentication, true);
}
#Override
public String protocol() {
return "http";
}
#Override
public String authScheme() {
return "ntlm";
}
protected void addCodec(ChannelHandlerContext ctx) throws Exception {
ChannelPipeline p = ctx.pipeline();
String name = ctx.name();
p.addBefore(name, (String)null, this.codec);
}
protected void removeEncoder(ChannelHandlerContext ctx) throws Exception {
this.codec.removeOutboundHandler();
}
protected void removeDecoder(ChannelHandlerContext ctx) throws Exception {
this.codec.removeInboundHandler();
}
#Override
protected Object newInitialMessage(ChannelHandlerContext channelHandlerContext) throws Exception {
InetSocketAddress raddr = this.destinationAddress();
String rhost;
if(raddr.isUnresolved()) {
rhost = raddr.getHostString();
} else {
rhost = raddr.getAddress().getHostAddress();
}
String host = rhost + ':' + raddr.getPort();
DefaultFullHttpRequest req = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.CONNECT, host, Unpooled.EMPTY_BUFFER, false);
req.headers().set(HttpHeaderNames.HOST, host);
req.headers().set("connection", "keep-alive");
// This initial request successfully reaches the server !
return req;
}
#Override
protected boolean handleResponse(ChannelHandlerContext channelHandlerContext, Object o) throws Exception {
if (o instanceof HttpResponse) {
response = (HttpResponse) o;
}
boolean finished = o instanceof LastHttpContent;
if(finished) {
status = response.status();
logger.info("Status: " + status);
if (!response.headers().isEmpty()) {
for (String name: response.headers().names()) {
for (String value: response.headers().getAll(name)) {
logger.debug("Header: " + name + " = " + value);
}
}
}
if(status.code() == 407) {
negotiate(channelHandlerContext, response);
}
else if(status.code() == 200){
logger.info("Client: NTLM exchange complete. Authenticated !");
}
else {
throw new ProxyConnectException(this.exceptionMessage("status: " + this.status));
}
}
return finished;
}
private void negotiate(ChannelHandlerContext channelHandlerContext, HttpResponse msg) throws Exception{
String ntlmHeader = msg.headers().get(HttpHeaderNames.PROXY_AUTHENTICATE);
if(ntlmHeader.equalsIgnoreCase("NTLM")){
logger.info("Client: Creating NTLM Type1Message");
//Send Type1Message
byte[] rawType1Message = ntlmContext.initSecContext(new byte[]{}, 0, 0);
Type1Message type1Message = new Type1Message(rawType1Message);
FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK);
String proxyAuthHeader = Base64.encode(type1Message.toByteArray());
logger.info("Setting proxyAuthHeader = " + proxyAuthHeader);
response.headers().set(HttpHeaders.Names.PROXY_AUTHORIZATION, proxyAuthHeader);
ByteBuf byteBuf = Unpooled.buffer(rawType1Message.length);
byteBuf.writeBytes(response.content());
//This is where the response is lost and never reaches the proxy server
sendToProxyServer(byteBuf);
// channelHandlerContext.writeAndFlush(response.content));
} else if (ntlmHeader.contains(NTLM_Prefix)) {
logger.info("Client: Creating NTLM Type3Message");
//Send Type3 Message
}
}
}
I finally figured out the problem. The NTLM proxy handler when it responds to the proxy's message was sending a FullHTTPResponse instead of FullHTTPRequest. Looks like Netty's pipeline was discarding the data written as response and this was not indicated in the logs.
DefaultFullHttpRequest req = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.CONNECT, host, Unpooled.EMPTY_BUFFER, false);
req.headers().set(HttpHeaderNames.HOST, host);
req.headers().set(HttpHeaders.Names.PROXY_AUTHORIZATION, "type3message");
sendToProxyServer(req);

Push pull on couchabase server side thro' couchbase lite client side

i have tried to create one small java code to handle couchbase lite database and to do push pull operation
senario in depth is as follows
what i did is i have created bucket named as sync_gateway,
and conected with couchbase server by below config.json
{
"interface":":4984",
"adminInterface":":4985",
"databases":{
"db":{
"server":"http://localhost:8091",
"bucket":"sync_gateway",
"sync":function(doc) {
channel(doc.channels);
}
}
}
}
this had created metadata in sync_gateway bucket on server,
the n i have written sample java code for local database CBL , and wrote functions for push pull operations ...
code:
package com.Testing_couchbaseLite;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import javax.naming.ldap.ManageReferralControl;
import org.apache.http.cookie.Cookie;
import com.couchbase.lite.Context;
import com.couchbase.lite.CouchbaseLiteException;
import com.couchbase.lite.Database;
import com.couchbase.lite.Document;
import com.couchbase.lite.JavaContext;
import com.couchbase.lite.Manager;
import com.couchbase.lite.ManagerOptions;
import com.couchbase.lite.QueryOptions;
import com.couchbase.lite.replicator.Replication;
import com.couchbase.lite.support.HttpClientFactory;
public class Test_syncGateWay {
private URL createSyncURL(boolean isEncrypted){
URL syncURL = null;
String host = "https://localhost"; //sync gateway ip
String port = "4984"; //sync gateway port
String dbName = "db";
try {
syncURL = new URL(host + ":" + port + "/" + dbName);
} catch (MalformedURLException me) {
me.printStackTrace();
}
return syncURL;
}
private void startReplications() throws CouchbaseLiteException {
try {
Map<String, Object> map = new HashMap<String, Object>();
map.put("id", "1");
map.put("name","ram");
Manager man = new Manager(new JavaContext(), Manager.DEFAULT_OPTIONS);
Database db = man.getDatabase("sync_gateway");
Document doc = db.createDocument();
doc.putProperties(map);
System.out.println("-------------done------------");
System.out.println(man.getAllDatabaseNames());
System.out.println(man.getDatabase("sync_gateway").getDocumentCount());
System.out.println(db.getDocument("1").getCurrentRevisionId());
System.out.println(db.exists());
Replication pull = db.createPullReplication(this.createSyncURL(true));
Replication push = db.createPushReplication(this.createSyncURL(true));
pull.setContinuous(true);
push.setContinuous(true);
pull.start();
push.start();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private void createDatabase() throws CouchbaseLiteException, IOException {
// TODO Auto-generated method stub
}
public static void main(String[] args) throws CouchbaseLiteException, IOException {
new Test_syncGateWay().startReplications();
}
}
now i am stating sync gateway by that config file and running java code to create document on CBL and CB server by push pull operation.
bt it is showing error as
Jul 08, 2016 10:27:21 AM com.couchbase.lite.util.SystemLogger e
SEVERE: RemoteRequest: RemoteRequest{GET, https://localhost:4984/db/_local/2eafda901c4de2fe022af262d5cc7d1c0cb5c2d2}: executeRequest() Exception: javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated. url: https://localhost:4984/db/_local/2eafda901c4de2fe022af262d5cc7d1c0cb5c2d2
so is there any misunderstanding in my concept??? and how do i resolve this problem??
You have not set up your Sync Gateway for SSL. You need to add the SSLCert and SSLPass keys to your config file.

Resources