I'm trying to send one very big http post request to stand alone neo4j server (neo4j-community-1.9.M01).
Bellow is the sample code that I'm using.
The input file: ideas/src/test/test-rest.txt contains one very big json string (more than (250k).
The problem is that I cannot control a lot of settings of the web server launched by the standalone version of neo4j. Probably there is some limit on the web server that prevent me to send big post requests. Could someone help me to find out this setting.
Alternative : could some one tell me how to replace the default webserver used by neo4j for example with tomcat.
The error that I receive on the client is:
Caused by: java.net.SocketException: Connection reset by peer: socket write error
at java.net.SocketOutputStream.socketWrite0(Native Method)
at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:92)
at java.net.SocketOutputStream.write(SocketOutputStream.java:136)
at java.io.BufferedOutputStream.write(BufferedOutputStream.java:105)
at java.io.FilterOutputStream.write(FilterOutputStream.java:80)
at org.apache.commons.httpclient.WireLogOutputStream.write(WireLogOutputStream.java:86)
at com.sun.jersey.client.apache.DefaultApacheHttpMethodExecutor$3.writeRequest(DefaultApacheHttpMethodExecutor.java:186)
at org.apache.commons.httpclient.methods.EntityEnclosingMethod.writeRequestBody(EntityEnclosingMethod.java:499)
at org.apache.commons.httpclient.HttpMethodBase.writeRequest(HttpMethodBase.java:2114)
at org.apache.commons.httpclient.HttpMethodBase.execute(HttpMethodBase.java:1096)
at org.apache.commons.httpclient.HttpMethodDirector.executeWithRetry(HttpMethodDirector.java:398)
at org.apache.commons.httpclient.HttpMethodDirector.executeMethod(HttpMethodDirector.java:171)
at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:397)
at com.sun.jersey.client.apache.DefaultApacheHttpMethodExecutor.executeMethod(DefaultApacheHttpMethodExecutor.java:210)
Here are some logs from the web client:
11-11#08:28:01 INFO (HttpMethodDirector.java:445) - Retrying request
11-11#08:28:01 DEBUG (HttpConnection.java:692) - Open connection to localhost:7474
11-11#08:28:01 DEBUG ( Wire.java:70) - >> "POST /db/data/batch HTTP/1.1[\r][\n]"
11-11#08:28:01 DEBUG (HttpMethodBase.java:1352) - Adding Host request header
11-11#08:28:01 DEBUG ( Wire.java:70) - >> "Accept: application/json; stream=true[\r][\n]"
11-11#08:28:01 DEBUG ( Wire.java:70) - >> "X-Stream: true[\r][\n]"
11-11#08:28:01 DEBUG ( Wire.java:70) - >> "Content-Type: application/json[\r][\n]"
11-11#08:28:01 DEBUG ( Wire.java:70) - >> "User-Agent: Jakarta Commons-HttpClient/3.1[\r][\n]"
11-11#08:28:01 DEBUG ( Wire.java:70) - >> "Content-Length: 246292[\r][\n]"
11-11#08:28:01 DEBUG ( Wire.java:70) - >> "Host: localhost:7474[\r][\n]"
11-11#08:28:01 DEBUG ( Wire.java:70) - >> "[\r][\n]"
11-11#08:31:22 DEBUG (HttpMethodDirector.java:404) - Closing the connection.
11-11#08:31:22 DEBUG (HttpMethodDirector.java:434) - Method retry handler returned false. Automatic recovery will not be attempted
11-11#08:31:22 DEBUG (HttpConnection.java:1178) - Releasing connection back to connection manager.
Here is the client code:
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.WebResource;
import com.sun.jersey.client.apache.ApacheHttpClient;
import org.apache.commons.io.FileUtils;
import org.neo4j.rest.graphdb.RequestResult;
import org.neo4j.rest.graphdb.UserAgent;
import javax.ws.rs.core.MediaType;
import java.io.*;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.HashMap;
import java.util.Map;
import static javax.ws.rs.core.MediaType.APPLICATION_JSON_TYPE;
public class Main {
private static final UserAgent userAgent = new UserAgent();
public static final MediaType STREAMING_JSON_TYPE = new MediaType(APPLICATION_JSON_TYPE.getType(),APPLICATION_JSON_TYPE.getSubtype(), stringMap("stream","true"));
public static void main(String[] args) throws URISyntaxException, IOException {
String data = FileUtils.readFileToString(new File("ideas/src/test/test-rest.txt"));
Client client = createClient();
WebResource resource = client.resource(new URI("http://localhost:7474/db/data/batch"));
WebResource.Builder builder = resource.accept(STREAMING_JSON_TYPE).header("X-Stream", "true");
builder.entity( toInputStream(data), APPLICATION_JSON_TYPE );
System.out.println(RequestResult.extractFrom(builder.post(ClientResponse.class)));
}
private static InputStream toInputStream(String data) throws IOException {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream(4024 * 1024);
outputStream.write(data.getBytes());
byte[] buf = outputStream.toByteArray();
ByteArrayInputStream inputStream = new ByteArrayInputStream(buf);
return inputStream;
}
protected static Client createClient1() {
Client client = Client.create();
client.setConnectTimeout(800);
client.setReadTimeout(800);
client.setChunkedEncodingSize(80 * 1024);
userAgent.install(client);
return client;
}
protected static Client createClient() {
Client client = ApacheHttpClient.create();
return client;
}
private static Map<String, String> stringMap(String stream, String aTrue) {
HashMap<String, String> result = new HashMap<String, String>();
result.put(stream, aTrue);
return result;
}
}
Thanks in advance.
I found the reason of the problem.
I was running under Virtual BOX 4.2.0 with Windows XP guest machine and windows 7 host machine machine.
After putting the server on another machine, the problem disappeared.
I investigated with wireshark, before the failure I saw a lot of tcp packages that were not acknowledged and therefore retransmitted.
My question is still opened:how to replace the default webserver used by neo4j for example with tomcat?
Related
How do I configure Micronaut app using Vert.x and testcontainers? I'm trying:
application-test.yml
datasources:
default:
url: jdbc:tc:mysql:8:///db
driverClassName: org.testcontainers.jdbc.ContainerDatabaseDriver
vertx:
mysql:
client:
uri: jdbc:tc:mysql:8:///db
Tests with micronaut-data-jdbc work, but with micronaut-vertx-mysql-client not work:
Error:
Message: Cannot parse invalid connection URI: jdbc:tc:mysql:8:///db
I'm not very familiar with testecontainers, but it seems like it doesn't come up with a fixed port, so I don't know how to configure the connection URI.
Thanks!
It might be a problem that micronaut-vertx-mysql-client does not support the Testcontainers JDBC URL scheme (hard to say without further logs).
In this case, I would suggest to use Testcontainers with database container objects instead of the special JDBC URL.
I got a solution to the problem:
Micronaut + jdbc hikari + vertx mysql client + flyway mysql
package br.com.app;
import io.micronaut.context.ApplicationContext;
import io.micronaut.context.env.PropertySource;
import io.micronaut.core.util.CollectionUtils;
import io.micronaut.http.HttpRequest;
import io.micronaut.http.HttpStatus;
import io.micronaut.http.client.HttpClient;
import io.micronaut.runtime.EmbeddedApplication;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.testcontainers.containers.MySQLContainer;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
#Testcontainers
class AuthTest {
static Logger log = LoggerFactory.getLogger(AuthTest.class.getName());
#Container
static MySQLContainer mysql = new MySQLContainer("mysql:8");
private HttpClient client;
private static EmbeddedApplication application;
private static ApplicationContext context;
#BeforeAll
public static void initTests(){
log.info("Mysql is running {}, port {}", mysql.isRunning(), mysql.getFirstMappedPort());
var port = mysql.getFirstMappedPort();
var host = mysql.getHost();
var database = mysql.getDatabaseName();
var user = mysql.getUsername();
var password = mysql.getPassword();
var url = String.format("jdbc:mysql://%s:%s/%s", host, port, database);
application = ApplicationContext.run(EmbeddedApplication.class,
PropertySource.of(
"test",
CollectionUtils.mapOf(
"vertx.mysql.client.port", port,
"vertx.mysql.client.host", host,
"vertx.mysql.client.database", database,
"vertx.mysql.client.user", user,
"vertx.mysql.client.password", password,
"datasources.default.url", url,
"datasources.default.username", user,
"datasources.default.password", password,
"flyway.datasources.default.enabled", true
)
));
context = application.getApplicationContext();
}
#BeforeEach
void beforeEach(){
this.authService = context.getBean(AuthService.class);
this.client = context.getBean(HttpClient.class);
}
#Test
void testItWorks() {
Assertions.assertTrue(application.isRunning());
}
// api tests
}
Help links:
https://dev.to/major13ua/micronaut-integration-testing-using-testcontainers-2e30
https://github.com/major13ua/micronaut-tc/blob/main/src/test/java/com/example/testcontainer/controller/DemoControllerTest.java
I know config.setSendServerVersion(false); should hide the server version from Header.
But it's not happening even I debug the code get into
public void setSendServerVersion(boolean sendServerVersion) {
this._sendServerVersion = sendServerVersion;
}
And found sendServerVersion always true even we are passing false.
Here is how I'm calling
HttpConfiguration http_config = new HttpConfiguration();
http_config.setOutputBufferSize(32768);
http_config.setSendServerVersion(false);
Can somebody help me out with how to remove the header server?
Content-Type: text/html;charset=utf-8
Date: Thu, 28 Oct 2021 10:57:29 GMT
Server: Jetty(9.4.42.v20210604)
Strict-Transport-Security: max-age=31556926; includeSubDomains
Transfer-Encoding: chunked
.
.
.
Configuring the common Response headers is definitely done with the HttpConfiguration, but it has to be tied to a specific ServerConnector for that configuration to have any impact.
Take this example.
Available on jetty-project/embedded-jetty-cookbook as HttpConfigExample
Pay attention to the branch on embedded-jetty-cookbook, as there are examples for jetty-9.4.x, jetty-10.0.x, and also jetty-11.0.x
package org.eclipse.jetty.cookbook;
import java.io.IOException;
import java.net.URI;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.client.HttpClient;
import org.eclipse.jetty.client.api.ContentResponse;
import org.eclipse.jetty.server.HttpConfiguration;
import org.eclipse.jetty.server.HttpConnectionFactory;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.server.handler.AbstractHandler;
import org.eclipse.jetty.util.component.LifeCycle;
public class HttpConfigExample
{
public static void main(String[] args) throws Exception
{
Server server = new Server();
HttpConfiguration httpConfigOff = new HttpConfiguration();
httpConfigOff.setSendDateHeader(false);
httpConfigOff.setSendServerVersion(false);
httpConfigOff.setSendXPoweredBy(false);
ServerConnector connectorOff = new ServerConnector(server, new HttpConnectionFactory(httpConfigOff));
connectorOff.setPort(9090);
server.addConnector(connectorOff);
HttpConfiguration httpConfigDefault = new HttpConfiguration();
ServerConnector connectorDefault = new ServerConnector(server, new HttpConnectionFactory(httpConfigDefault));
connectorDefault.setPort(9191);
server.addConnector(connectorDefault);
server.setHandler(new AbstractHandler()
{
#Override
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
{
response.setCharacterEncoding("utf-8");
response.setContentType("text/plain");
response.getWriter().println("Greetings.");
baseRequest.setHandled(true);
}
});
HttpClient client = new HttpClient();
try
{
client.start();
server.start();
// Let's show what the default Response headers look like.
dumpResponse("Default Response", client.GET(URI.create("http://localhost:9191/")));
// Let's show what the default Response headers look like.
dumpResponse("Configured Response", client.GET(URI.create("http://localhost:9090/")));
}
finally
{
LifeCycle.stop(server);
LifeCycle.stop(client);
}
}
private static void dumpResponse(String heading, ContentResponse response)
{
System.out.printf("--- %s ---%n", heading);
System.out.printf("Request to %s%n", response.getRequest().getURI());
System.out.printf("Response: %s %d %s%n", response.getVersion(), response.getStatus(), response.getReason());
System.out.println(response.getHeaders());
System.out.println(response.getContentAsString());
}
}
This sets up 2 ServerConnector objects ...
On port 9191 is the default HttpConfiguration
On port 9090 is the configured (some common response headers turned off) HttpConfiguration
If we make a simple request to both ports we can see the results ...
--- Default Response ---
Request to http://localhost:9191/
Response: HTTP/1.1 200 OK
Date: Thu, 28 Oct 2021 13:22:41 GMT
Content-Type: text/plain;charset=UTF-8
Content-Length: 11
Server: Jetty(9.4.44.v20210927)
Greetings.
--- Configured Response ---
Request to http://localhost:9090/
Response: HTTP/1.1 200 OK
Content-Type: text/plain;charset=UTF-8
Content-Length: 11
Greetings.
I'm having a trouble sending an email using Google's SMTP Server. I've looked for a solution but i have not found one. So here's the code.
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.PasswordAuthentication;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
...
...
...
private void jButton2ActionPerformed(java.awt.event.ActionEvent evt)
{
Properties props = new Properties();
props.put("true", "mail.smtp.auth");
props.put("true","mail.smtp.starttls.enable");
props.put("smtp.gmail.com", "mail.smtp.host");
props.put("587", "mail.smtp.port");
Session sess=Session.getDefaultInstance(props,
new javax.mail.Authenticator() {
protected PasswordAuthentication getPasswordAuthentication(){
return new PasswordAuthentication("myemail#gmail.com", "mypassword");
}
}
);
try{
Message message= new MimeMessage(sess);
message.setFrom(new InternetAddress("myemail#gmail.com"));
message.setRecipients(Message.RecipientType.TO,InternetAddress.parse("myemail#gmail.com"));
message.setSubject("message");
message.setText("text");
Transport.send(message);
JOptionPane.showMessageDialog(null, "Sent!");
}catch(Exception e){
JOptionPane.showMessageDialog(null, e);
}
Each time when i press the button, it show me this error:
javax.mail.MessagingException: Could not connect to SMTP host: localhost, port: 25;
nested exception is:
java.net.ConnectException: Connection refused: connect
I've tried 3 ports: 25, 465, 587 , but it always gives me that error. I even made new rules for the port 25 to the firewall settings, but that doesn't seem to do the trick. Any thoughts what am i doing wrong? Could hibernate cause the problem? Because i'm using it in this project. Plus, i have installed mysql.
Your program is trying to connect to a local port, that's why it failed. If your listing is real code, you got the key and value backwards in the props.set statements.
I want to send a SOAP request through SSL to SOAP server (Microsoft IIS server). When I test the SOAP request through the soapUI tool with SSL - Keystore configurations it returns response correctly. But Using following code it returns "HTTP/1.1 400 Bad Request"
I used httpclient-4.2.3 and httpcore-4.2.2.
import java.security.KeyStore;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.BasicClientConnectionManager;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpParams;
import org.apache.http.util.EntityUtils;
public final static void main(String[] args) throws Exception {
DefaultHttpClient httpclient = new DefaultHttpClient();
try {
KeyStore keyStore = KeyStore.getInstance("JKS");
FileInputStream instream1 = new FileInputStream(new File("C:\\CCDKeyStore\\mykeystore.jks"));
try {
keyStore.load(instream1, "1214524".toCharArray());
} finally {
try { instream1.close(); } catch (Exception ignore) {}
}
SSLSocketFactory socketFactory = new SSLSocketFactory(keyStore,"1214524");
Scheme sch = new Scheme("https", 443, socketFactory);
SchemeRegistry schemeRegistry = httpclient.getConnectionManager().getSchemeRegistry();
schemeRegistry.register(sch);
final HttpParams httpParams = new BasicHttpParams();
DefaultHttpClient lHttpClient = new DefaultHttpClient(new BasicClientConnectionManager(schemeRegistry), httpParams);
String lUrl = "https://api.demo.server.com/XDS/Service.svc?wsdl";
StringBuffer lXmlBuffer = new StringBuffer();
lXmlBuffer.append("<s:Envelope xmlns:s=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:a=\"http://www.w3.org/2005/08/addressing\">\n");
lXmlBuffer.append("<s:Header>\n");
lXmlBuffer.append("<a:Action s:mustUnderstand=\"1\">urn:74347:4757:StoredQuery</a:Action>\n");
lXmlBuffer.append("<a:MessageID>urn:uuid:c6430690-412e-4744-afe1-233e2138f2d2</a:MessageID>\n");
.
.
.
.
.
.
lXmlBuffer.append("</Slot>\n");
lXmlBuffer.append("</AdhocQuery>\n");
lXmlBuffer.append("</query:AdhocQueryRequest>\n");
lXmlBuffer.append("</s:Body>\n");
lXmlBuffer.append("</s:Envelope>\n");
String lXml = lXmlBuffer.toString();
HttpPost lMethod = new HttpPost(lUrl);
HttpEntity lEntity = new StringEntity(lXml, "multipart/related", "utf-8");
lMethod.setHeader("SOAPAction", "urn:74347:4757:StoredQuery");
System.out.println(EntityUtils.toString(lEntity));
lMethod.setEntity(lEntity);
HttpResponse lHttpResponse = lHttpClient.execute(lMethod);
} finally {
httpclient.getConnectionManager().shutdown();
}
Any help on this highly appreciate
Thanks,
Mohan
Finally I found the answer...
Here the following line in above code contains content type as "multipart/related". But web service is expected the content type "application/soap+xml" since this is SOAP request. Please refer w3schools tutorial for further information
HttpEntity lEntity = new StringEntity(lXml, "multipart/related", "utf-8");
I'm trying to write a REST service in java using Jersey and Glassfish Grizzly. I have a very simple case working internally, but can't seem to call on the server from an external address. I've tried using a variety of different pairs of machines with externally visible IP's, and tried specifying the actual IP address in the server instead of localhost, but nothing works. I'm somewhat loosely following the official user guide here. My resource:
package resources;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
#Path("/simpleREST")
public class SimpleRESTResource
{
#GET
#Produces("text/plain")
public String getMessage()
{
return "Message from server\n";
}
}
And the server:
import java.io.IOException;
import java.net.URI;
import javax.ws.rs.core.UriBuilder;
import org.glassfish.grizzly.http.server.HttpServer;
import com.sun.jersey.api.container.grizzly2.GrizzlyServerFactory;
import com.sun.jersey.api.core.PackagesResourceConfig;
import com.sun.jersey.api.core.ResourceConfig;
public class Main
{
public static final URI BASE_URI = UriBuilder.fromUri("http://localhost").port(9998).build();
public static void main(String[] args) throws IOException
{
System.out.println("Starting grizzly...");
ResourceConfig rc = new PackagesResourceConfig("resources");
HttpServer myServer = GrizzlyServerFactory.createHttpServer(BASE_URI, rc);
System.out.println(String.format("Jersey app started with WADL available at %s/application.wadl\n" +
"Try out %s/simpleREST\nHit enter to stop it...", BASE_URI, BASE_URI));
System.in.read();
myServer.stop();
}
}
On the same machine, I can successfully interact with the server using
curl -X GET localhost:9998/simpleREST
OR
curl -X GET [external numeric address]:9998/simpleREST
Many thanks in advance for any suggestions.
SOLUTION
I have fixed this problem by setting the server URI to http://0.0.0.0:9998 instead of localhost, 127.0.0.1, or the actual address.
To make a server IP adress visible outside of localhost, you must fist open the neccessary firewall ports(if you have one), or use "0.0.0.0" instead of "localhost" in order for the server to listen to all IP addresses and network adapters. Before testing it in your local network, try pinging your server device from your client device to check if there is an actual connection or if the devices are not connected at all.
With Jersey and Grizzly 2.30, it's simpler:
final ResourceConfig rc = new ResourceConfig().packages("com.rest");
HttpServer httpServer = Grizzly
HttpServerFactory.createHttpServer(URI.create("http://0.0.0.0:9998/api/"), rc);
or, you can try these codes below:
ResourceConfig rc = new PackagesResourceConfig("your-rest-packages");
HttpHandler handler = ContainerFactory.createContainer(HttpHandler.class, rc);
server = new HttpServer();
server.getServerConfiguration().addHttpHandler(handler);
//attach listeners
InetAddress localHost = InetAddress.getLocalHost();
String localHostAddr = localHost.getHostAddress();
NetworkListener localHostListener = new NetworkListener("localhost", localHostAddr, port);
server.addListener(localHostListener);
InetAddress loopback = InetAddress.getLoopbackAddress();
String loopbackAddr = loopback.getHostAddress();
NetworkListener loopbackListener = new NetworkListener("loopback", loopbackAddr, port);
now your server could both list to localhost and loopback