Compressed GZIP Request sent to jetty using jersey-client is not working for FormDataMultiPart - jetty

Jersey Client code and jetty.xml -
...
public class App
{
public static void main( String[] args ) throws FileNotFoundException
{
String token = "abc";
String file = "C:\\importedcerts\\TestpkgRoll.log";
String uri = "http://localhost:8008/api/arsys/v1/entry/myattach1";
Client client = ClientBuilder.newBuilder()
.register(EncodingFilter.class)
.register(GZipEncoder.class)
.property(ClientProperties.USE_ENCODING, "gzip")
.register(MultiPartFeature.class).build();
FormDataMultiPart formDataMultiPart = new FormDataMultiPart();
// json data
String json = "{ \"values\" : { ";
json += "\"Submitter__c\" : \"Allen\", ";
json += "\"Short Description__c\" : \"testing 123\""
+ ", ";
json += "\"Attachment__c\" : \"testrollback.log\"";
json += " } }";
formDataMultiPart.field("entry", json,
MediaType.APPLICATION_JSON_TYPE);
StreamDataBodyPart streamDataBodyPart = new StreamDataBodyPart("attach-Attachment__c", new FileInputStream(new File(file)), "testrollback.log", MediaType.APPLICATION_OCTET_STREAM_TYPE);
formDataMultiPart.bodyPart(streamDataBodyPart);
Builder request = client.target(uri).request(MediaType.APPLICATION_JSON);
request.header("Authorization", "AR-JWT " + token);
request.header("Content-Encoding", "gzip");
Response response = null;
response = request.method("POST",
// Entity.json(json));
Entity.entity(formDataMultiPart, MediaType.MULTIPART_FORM_DATA_TYPE));
System.out.println(response);
}
}
<Call name="insertHandler">
<Arg>
<New id="GzipHandler" class="org.eclipse.jetty.server.handler.gzip.GzipHandler">
<Set name="minGzipSize"><Property name="jetty.gzip.minGzipSize" deprecated="gzip.minGzipSize" default="0"/></Set>
<Set name="checkGzExists"><Property name="jetty.gzip.checkGzExists" deprecated="gzip.checkGzExists" default="false"/></Set>
<Set name="inflateBufferSize"><Property name="jetty.gzip.inflateBufferSize" default="1024"/></Set>
<Set name="excludedAgentPatterns">
<Array type="String">
<Item><Property name="jetty.gzip.excludedUserAgent" deprecated="gzip.excludedUserAgent" default=".*MSIE.6\.0.*"/></Item>
</Array>
</Set>
<Call name="addIncludedMimeTypes">
<Arg><Array type="String">
<Item>application/octet-stream</Item>
</Array></Arg>
</Call>
<Call name="addExcludedMimeTypes">
<Arg><Array type="String">
<Item>application/json</Item>
</Array></Arg>
</Call>
</New>
</Arg>
</Call>
...
However above request processing fails with Exception -
org.jvnet.mimepull.MIMEParsingException: Missing start boundary
However in my client when I comment out as below
...
// .register(EncodingFilter.class)
// .register(GZipEncoder.class)
// .property(ClientProperties.USE_ENCODING, "gzip")
// request.header("Content-Encoding", "aplication/gzip, gzip");
...
I am able to process request successfully , what could be an issue when above portion is uncommented , is it in client code or jetty.xml which resides on server ?

You need to enable the GzipHandler on Jetty to have it process compressed content (request or response).
That XML block you pasted (from the gzip module on jetty-home) is not something you should be editing to enable GzipHandler, use the proper split of ${jetty.home} and ${jetty.base}, enable the gzip module, and then configure it with the appropriate properties that this split provides for you.
By default, the auto-decompression of request body content is disabled.
But setting GzipHandler.setInflateBufferSize(int) to a positive value the decompression (aka inflation) of request body content will occur.

Related

WebSphere MQ call failed with compcode '2' ('MQCC_FAILED') reason '2397' ('MQRC_JSSE_ERROR') while using jetty config for MQ Connection

I'm configuring MQ connection in jetty-env.xml file as :
<New id="myJmsConnection" class="org.eclipse.jetty.plus.jndi.Resource">
<Arg><Ref refid="wac"/></Arg>
<Arg>jms/mymq</Arg>
<Arg>
<New class="com.ibm.mq.jms.MQConnectionFactory">
<Set name="connectionNameList">x.x.x.x</Set>
<Set name="port">xxx</Set>
<Set name="queueManager">xxx</Set>
<Set name="channel">xxx.CHANNEL</Set>
<Set name="transportType">1</Set>
<Set name="SSLCipherSuite">xxxx</Set>
</New>
</Arg>
</New>
With the above configuration, when I run jetty I'm getting this error
nested exception is com.ibm.mq.MQException: JMSCMQ0001: WebSphere MQ call failed with compcode '2' ('MQCC_FAILED') reason '2397' ('MQRC_JSSE_ERROR')
But the same config values when I use in my Code to make MQ connection, I'm able to establish the connection
#Bean(name="MQConnectionFactory")
public ConnectionFactory connectionFactory() {
if (factory == null) {
factory = new MQConnectionFactory();
try {
factory.setConnectionNameList(env.getRequiredProperty(HOST));
factory.setPort(Integer.parseInt(env.getRequiredProperty(PORT)));
factory.setQueueManager(env.getRequiredProperty(QUEUE_MANAGER));
factory.setChannel(env.getRequiredProperty(CHANNEL));
factory.setTransportType(WMQConstants.WMQ_CM_CLIENT);
factory.setSSLCipherSuite(env.getRequiredProperty(SSL_CIPHER_SUITE));
factory.setStringProperty(WMQConstants.USERID, env.getRequiredProperty(QUEUE_USERID));
factory.setStringProperty(WMQConstants.PASSWORD, env.getRequiredProperty(QUEUE_PASSWORD));
} catch (JMSException e) {
throw new RuntimeException(e);
}
}
return factory;
}
My question is why the connectivity is working from the Java code but it throws MQ exception when configured in jetty-env.xml?

IllegalStateException: No LoginService for FormAuthenticator Jetty

I'm configuring a custom JAAS Login module in Jetty.
import org.eclipse.jetty.jaas.spi.AbstractLoginModule;
public class HybridLoginModule extends AbstractLoginModule
I add the file in: jetty-9.4.8/etc/login.conf
hybridRealm {
net.sf.jkniv.jaas.jetty.HybridLoginModule required
}
Enable the jaas in: jetty-9.4.8/start.ini
--module=jaas
jetty.jaas.login.conf=etc/login.conf
And config JAAS JAASLoginService in jetty-9.4.8/etc/jetty-webapp.xml
<Call name="addBean">
<Arg>
<New class="org.eclipse.jetty.jaas.JAASLoginService">
<Set name="name">Hybrid JAAS Realm</Set>
<Set name="LoginModuleName">hybridRealm</Set>
</New>
</Arg>
</Call>
But when I start jetty server java -jar start.jar the exception is throw
IllegalStateException: No LoginService for FormAuthenticator
java.lang.IllegalStateException: No LoginService for org.eclipse.jetty.security.authentication.FormAuthenticator#25084a1e in org.eclipse.jetty.security.ConstraintSecurityHandler#156b88f5
at org.eclipse.jetty.security.authentication.LoginAuthenticator.setConfiguration(LoginAuthenticator.java:76)
at org.eclipse.jetty.security.authentication.FormAuthenticator.setConfiguration(FormAuthenticator.java:131)
The jetty documentation it's ambiguous, to solution the configuration problem set the realm-name property from web.xml file to same value from <Set name="Name"> proprety, no <Set name="LoginModuleName">.
web.xml file:
<realm-name>xyzREALM</realm-name>
jetty-webapp.xml file:
<New class="org.eclipse.jetty.jaas.JAASLoginService">
<Set name="Name">xyzREALM</Set>
<Set name="LoginModuleName">hybridRealm</Set>
</New>

Negative response time in Jetty server access log

I'm running on Jetty and my access log is configured to show the response time.
today I noticed that a very minimal amount of the requests (about 30 out of 600K) have a negative response time and I was wondering if anyone ever encountered such a behavior.
This is a sample of my response:
<[IP]> - - <[date]> "POST <[url]> HTTP/1.0" 201 461 -18096
In case you want to identify this in the access log - this is the grep command i used:
grep --color "-[0-9][0-9]*" server-access.2013_12_09.log
Jetty Version: 8.1.8
Setup in jetty.xml:
<New id="request-log-handler" class="org.eclipse.jetty.server.handler.RequestLogHandler">
<Set name="requestLog">
<New class="org.eclipse.jetty.server.NCSARequestLog">
<Arg>
<Property name="logging.httpAccessLog" default="logs/app-access.yyyy_mm_dd.log" />
</Arg>
<Set name="retainDays">
<Property name="logging.accessLogRetentionInDays" default="10" />
</Set>
<Set name="append">
<Property name="logging.httpAccessLogAppend" default="true" />
</Set>
<!-- logs referer and user agent -->
<Set name="extended">
<Property name="logging.httpAccessLogExtended" default="false" />
</Set>
<!-- response time -->
<Set name="logLatency">
<Property name="logging.httpAccessLogLatency" default="true" />
</Set>
</New>
</Set>
Using Jetty 9.1.0.
Key:
<name> = optional / configurable entry on line
{name} = mandatory entry
<servername> {X-Forwarded-For||remote-addr} - {authentication/principal/name} [{request-timestamp}] "{method} {uri} {protocol}" {response-status-code} {response-content-length} <extended-log> <cookies> <latency>
Where:
<servername> can be the request/Host header
<extended-log> can be "{referer} {user-agent}"
<cookies> can be " -" or "{cookie.name}={cookie-value};"
<latency> can be (now - request.getTimeStamp())
Interestingly, it appears that your system clock adjusted during a request. A full 18 seconds!
Here's why this is the leading theory ...
The request.timestamp is set when the request starts, then the latency is computed later during the access/request logging. For there to be a negative value, either something outside of Jetty itself reset the request.timeout, or the system clock changed.

Jetty ServletContainerInitialization (SCI ) doesn't call an Initializer provided inside a web-fragment

Here is the scenario,
webapp contains a web.xml
one of the jars contain ServletContainerInitializer
META-INF/services/javax.servlet.ServletContainterInitializer
We are pro grammatically starting jetty, by using XMLConfiguration which is configured with a server object.
XmlConfiguration configuration = new XmlConfiguration(in);
if (type.isInstance(server))
{
configuration.configure(server);
return;
}
boolean success = false;
for (Handler handler : ((Server) server).getHandlers())
{
if (type.isInstance(handler))
{
configuration.configure(handler);
success = true;
}
}
here is the XML file that is used.
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<Configure class="org.eclipse.jetty.server.Server" id="Server">
<Set name="ThreadPool">
<New class="org.eclipse.jetty.util.thread.QueuedThreadPool">
<Set name="minThreads">2</Set>
<Set name="maxThreads">10</Set>
<Set name="detailedDump">false</Set>
</New>
</Set>
<Call name="addConnector">
<Arg>
<New class="org.eclipse.jetty.server.nio.SelectChannelConnector">
<Set name="port">8080</Set>
<Set name="maxIdleTime">30000</Set>
<Set name="Acceptors">2</Set>
<Set name="statsOn">false</Set>
</New>
</Arg>
</Call>
<Set name="handler">
<New class="org.eclipse.jetty.webapp.WebAppContext">
<Arg type="String">src/main/webapp</Arg>
<Arg type="String">/</Arg>
<Set name="extraClasspath">S:/git/projects/p1/target/classes;
S:/maven.repo/org/apache/ahc/1.1.2/ahc-1.1.2.jar;
S:/maven.repo/com/sun/xml/bind/jaxb-xjc/2.2.3.20110115/jaxb-xjc-2.2.3.20110115.jar;
S:/maven.repo/com/springsource/org/hsqldb/1.8.0.10/hsqldb-1.8.0.10.jar;
S:/maven.repo/com/springsource/org/jdom/1.0.0/jdom-1.0.0.jar;
S:/maven.repo/org/apache/mina/1.1.9/mina-1.1.9.jar;
S:/maven.repo/com/springsource/com/mysql/jdbc/5.1.6/jdbc-5.1.6.jar;
</Set>
</New>
</Set>
<Set name="stopAtShutdown">true</Set>
<Set name="sendServerVersion">true</Set>
<Set name="sendDateHeader">true</Set>
<Set name="gracefulShutdown">1000</Set>
<Set name="dumpAfterStart">false</Set>
<Set name="dumpBeforeStop">false</Set>
</Configure>
When invoked from CLI, jetty DeploymentManager scans the classpath and calls the ServletContainerInitializer provided inside the jar files. What is the equivalent for that to be provided in the XML config file?
When the code is deployed as a war into a jetty installation everything works as expected.
So, that confirms everything is correct.
Nambi,
Here's a link to the jetty documentation page that discusses using annotations in embedded mode: http://www.eclipse.org/jetty/documentation/current/using-annotations-embedded.html
You just need to do the equivalent of the java code in xml - which is always in jetty very straightforward. If you need hints, then have a look at your distro and see what the etc/jetty-annotations.xml file is doing.
Also, if you have annotations inside of jars that are on the extraClasspath, then you need to be using 9.0.6-SNAPSHOT of jetty as I've only just implemented that feature :)
Jan

Nexus / Jetty doesn't want to start anymore: Unresolved address

We have a Nexus server which worked fine until friday. Nexus was stopped and since we are unable to start it again but I can't figure out why ?
I think it's a Jetty problem. Here is the stack strace:
jvm 1 | 2012-08-13 09:31:10 WARN [er_start_runner] - org.mortbay.log - failed SelectChannelConnector#*:8080
jvm 1 | java.net.SocketException: Unresolved address
jvm 1 | at sun.nio.ch.Net.translateToSocketException(Net.java:58)
jvm 1 | at sun.nio.ch.Net.translateException(Net.java:84)
jvm 1 | at sun.nio.ch.Net.translateException(Net.java:90)
jvm 1 | at sun.nio.ch.ServerSocketAdaptor.bind(ServerSocketAdaptor.java:61)
jvm 1 | at org.mortbay.jetty.nio.SelectChannelConnector.open(SelectChannelConnector.java:216)
The configuration is (jetty.xml):
<Configure id="Server" class="org.mortbay.jetty.Server">
<Call name="addConnector">
<Arg>
<New class="org.mortbay.jetty.nio.SelectChannelConnector">
<Set name="host">${application-host}</Set>
<Set name="port">${application-port}</Set>
</New>
</Arg>
</Call>
<Set name="handler">
<New id="Contexts" class="org.mortbay.jetty.handler.ContextHandlerCollection">
<!-- The following configuration is REQUIRED, and MUST BE FIRST.
It makes the Plexus container available for use in the Nexus webapp. -->
<Call name="addLifeCycleListener">
<Arg>
<New class="org.sonatype.plexus.jetty.custom.InjectExistingPlexusListener" />
</Arg>
</Call>
<!-- The following configuration disables JSP taglib support, the validation of which
slows down Jetty's startup significantly. -->
<Call name="addLifeCycleListener">
<Arg>
<New class="org.sonatype.plexus.jetty.custom.DisableTagLibsListener" />
</Arg>
</Call>
</New>
</Set>
<New id="NexusWebAppContext" class="org.mortbay.jetty.webapp.WebAppContext">
<Arg><Ref id="Contexts"/></Arg>
<Arg>${webapp}</Arg>
<Arg>${webapp-context-path}</Arg>
<Set name="extractWAR">false</Set>
</New>
<Set name="stopAtShutdown">true</Set>
<Set name="sendServerVersion">true</Set>
<Set name="sendDateHeader">true</Set>
<Set name="gracefulShutdown">1000</Set>
</Configure>
and the plexus.properties:
application-port=8081
application-host=0.0.0.0
runtime=${basedir}/runtime
apps=${runtime}/apps
nexus-work=${basedir}/../../data/nexus/sonatype-work/nexus
nexus-app=${runtime}/apps/nexus
webapp=${runtime}/apps/nexus/webapp
webapp-context-path=/nexus
security-xml-file=${nexus-work}/conf/security.xml
application-conf=${nexus-work}/conf
runtime-tmp=${runtime}/tmp
# If this file is present, it will be used to configure Jetty.
jetty.xml=${basedir}/conf/jetty.xml
# Uncomment this to use the debug js files
#index.template.file=templates/index-debug.vm
Nexus version is 1.9.2.3
I can't understand:
why it wants to start a connector at port 8080 (while I only set port 8081) and
what means the address * (and why not 0.0.0.0) ? And of course why it doesn't want to start anymore ?
Thanks a lot for all your ideas!
I cannot comment on the 8080 vs 8081 issue, but as for the SocketException ...
The SocketException: unresolved address is usually due to some sort of host/dns/resolve configuration issue present on your system.
The most basic testcase for java that might help identify the issue would be the following
import java.net.InetAddress;
import java.net.InetSocketAddress;
public class AddrTest
{
public static void main(String[] args)
{
try
{
InetAddress addr = InetAddress.getByName("0.0.0.0");
System.out.println("InetAddress => " + addr);
System.out.println("InetAddress.isAnyLocalAddress = " + addr.isAnyLocalAddress());
System.out.println("InetAddress.isLinkLocalAddress = " + addr.isLinkLocalAddress());
System.out.println("InetAddress.isLoopbackAddress = " + addr.isLoopbackAddress());
InetSocketAddress isockaddr = new InetSocketAddress(addr,8080);
System.out.println("InetSocketAddr = " + isockaddr);
System.out.println("InetSocketAddr.isUnresolved = " + isockaddr.isUnresolved());
}
catch (Throwable e)
{
e.printStackTrace();
}
}
}
Run this, and you should have the output
InetAddress => /0.0.0.0
InetAddress.isAnyLocalAddress = true
InetAddress.isLinkLocalAddress = false
InetAddress.isLoopbackAddress = false
InetSocketAddr = /0.0.0.0:8080
InetSocketAddr.isUnresolved = false
What's important to note are the 2 lines...
InetAddress.isAnyLocalAddress = true - means that java + OS reports this as the ANY addr
InetSocketAddr.isUnresolved = false - means that java + OS was able to resolve this socket address
If you get an exception during this test, then you have some sort of fundamental host resolution issue on your system (dns, dhcp. vpn, etc/hosts, no IPv4 available, etc...), nothing you do in java, jetty, or nexus can fix this sort of issue. You'll need to address this (no pun intended) at the OS / Networking level.
I had a similar issue. Jetty was running inside docker container (jetty:9.3.24-jre8). You need to comment out line about http.host in start.ini:
#jetty.http.host='0.0.0.0'
Network interfaces get mixed up for some reason.
Solved!
The file jetty.xml had only the 'r' permission which is not enough: it must have the 'x' permission too. So Jetty was unable to read the file jetty.xml and in that case it tries to start a default connector on '*:8080' => * is not resolvable (I don't know why they used * instead of 0.0.0.0 ???)
So it was a configuration issue.