gzip compression not working in Solr 5.1 - solr

I'm trying to apply gzip compression in Solr 5.1. I understand that Running Solr on Tomcat is no longer supported from Solr 5.0, so I've tried to implement it in Solr.
I've downloaded jetty-servlets-9.3.0.RC0.jar and placed it in my webapp\WEB-INF folder, and have added the following in webapp\WEB-INF\web.xml:
<filter>
<filter-name>GzipFilter</filter-name>
<filter-class>org.eclipse.jetty.servlets.GzipFilter</filter-class>
<init-param>
<param-name>methods</param-name>
<param-value>GET,POST</param-value>
<param-name>mimeTypes</param-name>
<param-value>text/html,text/plain,text/xml,text/json,text/javascript,text/css,application/xhtml+xml,application/javascript,image/svg+xml,application/json,application/xml; charset=UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>GzipFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
However, when I start Solr and check the browser, there's no gzip compression, and I only get the following at the Response Headers output:
Content-Type:text/plain;charset=UTF-8
Transfer-Encoding:chunked
Is there anything which I configure wrongly or might have missed out? I'm also running zookeeper-3.4.6.

Download a kosher version of Jetty that closely matches what is currently in Solr: http://www.eclipse.org/jetty/download.html
Extract that .zip to a location you will discard.
Copy out these files to your copy of jetty in Solr (located in path-to-solr/server/):
modules/gzip.mod
etc/gzip.xml
Modify modules/gzip.mod:
#
# GZIP module
# Applies GzipHandler to entire server
#
[depend]
server
[xml]
etc/jetty-gzip.xml
[ini-template]
## Minimum content length after which gzip is enabled
jetty.gzip.minGzipSize=2048
## Check whether a file with *.gz extension exists
jetty.gzip.checkGzExists=false
## Gzip compression level (-1 for default)
jetty.gzip.compressionLevel=-1
## User agents for which gzip is disabled
jetty.gzip.excludedUserAgent=.*MSIE.6\.0.*
Modify etc/gzip.xml:
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd">
<!-- =============================================================== -->
<!-- Mixin the GZIP Handler -->
<!-- This applies the GZIP Handler to the entire server -->
<!-- If a GZIP handler is required for an individual context, then -->
<!-- use a context XML (see test.xml example in distribution) -->
<!-- =============================================================== -->
<Configure id="Server" class="org.eclipse.jetty.server.Server">
<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="2048"/>
</Set>
<Set name="checkGzExists">
<Property name="jetty.gzip.checkGzExists" deprecated="gzip.checkGzExists" default="false"/>
</Set>
<Set name="compressionLevel">
<Property name="jetty.gzip.compressionLevel" deprecated="gzip.compressionLevel" default="-1"/>
</Set>
<Set name="excludedAgentPatterns">
<Array type="String">
<Item>
<Property name="jetty.gzip.excludedUserAgent" deprecated="gzip.excludedUserAgent" default=".*MSIE.6\.0.*"/>
</Item>
</Array>
</Set>
<Set name="includedMethods">
<Array type="String">
<Item>GET</Item>
<Item>POST</Item>
</Array>
</Set>
<Set name="includedPaths"><Array type="String"><Item>/*</Item></Array></Set>
<Set name="excludedPaths"><Array type="String"><Item>*.gz</Item></Array></Set>
<Call name="addIncludedMimeTypes"><Arg><Array type="String">
<Item>text/html</Item>
<Item>text/plain</Item>
<Item>text/xml</Item>
<Item>application/xml</Item><!-- IMPORTANT - DO NOT FORGET THIS LINE -->
<Item>application/xhtml+xml</Item>
<Item>text/css</Item>
<Item>application/javascript</Item>
<Item>image/svg+xml</Item>
</Array></Arg></Call>
<!--
<Call name="addExcludedMimeTypes"><Arg><Array type="String"><Item>some/type</Item></Array></Arg></Call>
-->
</New>
</Arg>
</Call>
</Configure>
Here's the part that should make you cringe a bit.
Modify bin\solr.cmd
...
set "SOLR_JETTY_CONFIG=--module=http,gzip"
...
set "SOLR_JETTY_CONFIG=--module=https,gzip"
...
Notice that --module=http was already there. Just add ",gzip" so it matches the lines above.
I would prefer finding a better way of specifying the gzip module to load, but I don't know how. If you know how, please reply to this answer and tell me how because I hate modifying a script that comes with a product--it's a maintenance nightmare and, well, I think you get the picture.
After this, restart the solr server and gzip should now be enabled--at least for &wt=xml, which is sent back as Content-Type: application/xml.
You can add what you need to the etc/gzip.xml and restart the solr server for it to recognize your changes.
I tested with and without compression of 1000 documents. For me, it was the difference between 3.8 MB and 637 KB.

Related

Problems while using ANT for creating HTML (junit style) report

I am trying to generate an HTML/Junit Style report for the jMeter tests by using ANT. I have created a build file for this and have done all the pre-requisites like:
set the required variables like java home, ant home, path variables; put the ant build file and the required .jmx file (for jmeter execution) in a folder and calling "ant" command pointing at the same folder.
I tried calling the ant build file by giving commands as ant and ant -Dtest="Sample Workload Script".
The issue i get is that when i run this commands it reaches to the point of executing the test plan and then gives a java platform error (as shown in attached image) and stops the build. Any pointers to what might be causing this?
Java Platform Error when running the ANT Build file
I read somewhere that the ANT version may not be compatible with java 1.8. Speaking of which i am using Ant 1.9.7 and java 1.8.73
My build file:
<?xml version="1.0"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<project name="ant-jmeter" default="all">
<description>
Sample build file for use with ant-jmeter.jar
See http://www.programmerplanet.org/pages/projects/jmeter-ant-task.php
To run a test and create the output report:
ant -Dtest=script
To run a test only:
ant -Dtest=script run
To run report on existing test output
ant -Dtest=script report
The "script" parameter is the name of the script without the .jmx suffix.
Additional options:
-Dshow-data=y - include response data in Failure Details
-Dtestpath=xyz - path to test file(s) (default user.dir).
N.B. Ant interprets relative paths against the build file
-Djmeter.home=.. - path to JMeter home directory (defaults to parent of this build file)
-Dreport.title="My Report" - title for html report (default is 'Load Test Results')
Deprecated:
-Dformat=2.0 - use version 2.0 JTL files rather than 2.1
</description>
<property name="testpath" value="${user.dir}"/> <!--<property name="testpath" value="${user.dir}"/>-->
<property name="jmeter.home" value="C:\apache-jmeter-3.0"/>
<property name="report.title" value="Load Test Results"/>
<!-- Name of test (without .jmx) -->
<property name="test" value="Test"/>
<!-- Should report include response data for failures? -->
<property name="show-data" value="n"/>
<property name="format" value="2.1"/>
<condition property="style_version" value="">
<equals arg1="${format}" arg2="2.0"/>
</condition>
<condition property="style_version" value="_21">
<equals arg1="${format}" arg2="2.1"/>
</condition>
<condition property="funcMode">
<equals arg1="${show-data}" arg2="y"/>
</condition>
<condition property="funcMode" value="false">
<not>
<equals arg1="${show-data}" arg2="y"/>
</not>
</condition>
<!-- Allow jar to be picked up locally -->
<path id="jmeter.classpath">
<fileset dir="${basedir}">
<include name="ant-jmeter*.jar"/>
</fileset>
</path>
<taskdef
name="jmeter"
classname="org.programmerplanet.ant.taskdefs.jmeter.JMeterTask"/>
<!--classpathref="jmeter.classpath"-->
<!--classpathref="C:\apache-jmeter-3.0\extras"-->
<target name="all" depends="run,report"/>
<target name="run">
<echo>funcMode = ${funcMode}</echo>
<delete file="${testpath}/${test}.html"/>
<jmeter
jmeterhome="${jmeter.home}"
testplan ="${basedir}/${test}.jmx"
resultlog="${basedir}/${test}.jtl">
<!--
<jvmarg value="-Xincgc"/>
<jvmarg value="-Xmx128m"/>
<jvmarg value="-Dproperty=value"/>
<jmeterarg value="-qextra.properties"/>
-->
<!-- Force suitable defaults -->
<property name="jmeter.save.saveservice.output_format" value="xml"/>
<property name="jmeter.save.saveservice.assertion_results" value="all"/>
<property name="jmeter.save.saveservice.bytes" value="true"/>
<property name="file_format.testlog" value="${format}"/>
<property name="jmeter.save.saveservice.response_data.on_error" value="${funcMode}"/>
</jmeter>
</target>
<property name="lib.dir" value="${jmeter.home}/lib"/>
<!-- Use xalan copy from JMeter lib directory to ensure consistent processing with Java 1.4+ -->
<path id="xslt.classpath">
<fileset dir="${lib.dir}" includes="xalan*.jar"/>
<fileset dir="${lib.dir}" includes="serializer*.jar"/>
</path>
<target name="report" depends="xslt-report,copy-images">
<echo>Report generated at ${report.datestamp}</echo>
</target>
<target name="xslt-report" depends="_message_xalan">
<tstamp><format property="report.datestamp" pattern="yyyy/MM/dd HH:mm"/></tstamp>
<xslt
classpathref="xslt.classpath"
force="true"
in="${basedir}/${test}.jtl"
out="${basedir}/${test}.html"
style="${basedir}/jmeter-results-detail-report${style_version}.xsl">
<param name="showData" expression="${show-data}"/>
<param name="titleReport" expression="${report.title}"/>
<param name="dateReport" expression="${report.datestamp}"/>
</xslt>
</target>
<!-- Copy report images if needed -->
<target name="copy-images" depends="verify-images" unless="samepath">
<copy file="${basedir}/expand.png" tofile="${testpath}/expand.png"/>
<copy file="${basedir}/collapse.png" tofile="${testpath}/collapse.png"/>
</target>
<target name="verify-images">
<condition property="samepath">
<equals arg1="${testpath}" arg2="${basedir}" />
</condition>
</target>
<!-- Check that the xalan libraries are present -->
<condition property="xalan.present">
<and>
<!-- No need to check all jars; just check a few -->
<available classpathref="xslt.classpath" classname="org.apache.xalan.processor.TransformerFactoryImpl"/>
<available classpathref="xslt.classpath" classname="org.apache.xml.serializer.ExtendedContentHandler"/>
</and>
</condition>
<target name="_message_xalan" unless="xalan.present">
<echo>Cannot find all xalan and/or serialiser jars</echo>
<echo>The XSLT formatting may not work correctly.</echo>
<echo>Check you have xalan and serializer jars in ${lib.dir}</echo>
</target>
</project>
Update "jmeter" section of your build.xml file as follows:
<jmeter
jmeterhome="${jmeter.home}"
testplan ="${basedir}/${test}.jmx"
resultlog="${basedir}/${test}.jtl"
jmeterlogfile="${basedir}/jmeter.log"> <!-- add this line to enabled logging-->
Re-run your test and look into jmeter.log file under your C:\workspace\CPT folder - it should contain enough troubleshooting information so you will be able to find out the cause. If you have problems interpreting the log file - add it to your question.
References:
JMeter Ant Task
Five Ways To Launch a JMeter Test without Using the JMeter GUI

wso2 esb to download/get a local file

I have some static files (some are HTML, some are images and some are pure data files - like .csv or .xls etc) that I want to share through the ESB. I can make that happen if I run a separate HTTP server that will receive the request for these through ESB. Instead, I like to handle it in ESB itself. Based on the incoming request URL (say HTTP GET request - http://myesb.com:8280/getstatus.html ), I like to pull these static files from the local server's folders.
I tried the VFS method and it looks like has built in "refresh" mechanism that I don't want. I want to "GET" these data only when the clients are requesting for it.
In short, I like to have a simple mapping done like this:
http://myesb.com:8280/getstatus.html will fetch the contents of /var/myapp/status/appstatus.html file.
Update
I did the following sequence - don't know how to make it work :(
<sequence xmlns="http://ws.apache.org/ns/synapse" name="app1status">
<in>
<log level="custom">
<property name="Reached app1status page - in" value="app1 Status"/>
<property name="transport.vfs.ContentType" value="text/html"/>
<property xmlns:ns="http://org.apache.synapse/xsd" name="TRPURL:" expression="get-property('From')"/>
</log>
<property name="transport.vfs.FileURI" value="vfs:file:///opt/platform/traffic/app1status1.html" scope="transport" type="STRING"/>
<property name="HTTP_METHOD" value="GET"/>
<property name="ClientApiNonBlocking" action="remove" scope="axis2"/>
<header name="To" action="remove"/>
<property name="RESPONSE" value="true" scope="default" type="STRING"/>
</in>
<out>
<log level="custom">
<property name="::::::Out:::::Reached app1status" value=" From OUT"/>
<property name="messageType" value="text/html"/>
<property name="ContentType" value="text/html"/>
</log>
<send/>
</out>
</sequence>
Note the following in the <in> mediator:
<property name="transport.vfs.FileURI" value="vfs:file:///opt/platform/traffic/app1status1.html" scope="transport" type="STRING"/>
My intent is to get the content of the file appstatus1.html retrieved and send back as the response. But I am not able to get the contents retrieved and added to the "RESPONSE"
Let me know how it can be done.
Thanks for your time.
Define a RESTAPI and based on GET/PUT pull or post data to your server.

JPA does not write to table

I have the following JPA code, with all the values checked (ticket contains a valid bean, it ends without exception, etc.) It is executed, it does not throw any exceptions, yet in the end no data is written into the table.
I tried also retrieving a bean from the table, it also "works" (it is empty, so no data is returned).
The setup is
JBoss 6.1 Final
SQLServer 2008 Express (driver SQL JDBC 3 from MS)
The persistence code:
public String saveTicket() {
System.out.println("Controller saveTicket() ");
EntityManagerFactory factory = Persistence.createEntityManagerFactory("GesMan"); /* I know it would be better to share a single instance of factory, this is just for testing */
EntityManager entityMan = factory.createEntityManager();
entityMan.persist(this.ticket);
entityMan.close();
}
The persistence unit is
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="GesMan" transaction-type="JTA">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<jta-data-source>java:/GesManDS</jta-data-source>
<class>es.caib.gesma.gesman.Ticket</class>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.SQLServerDialect"/>
<property name="hibernate.transaction.manager_lookup_class"
value="org.hibernate.transaction.JBossTransactionManagerLookup"/>
<property name="hibernate.show_sql" value="true"/>
</properties>
</persistence-unit>
</persistence>
The datasource
<datasources>
<local-tx-datasource>
<jndi-name>GesManDS</jndi-name>
<connection-url>jdbc:sqlserver://spsigeswnt14.caib.es:1433;DatabaseName=TEST_GESMAN</connection-url>
<driver-class>com.microsoft.sqlserver.jdbc.SQLServerDriver</driver-class>
<user-name>thisis</user-name>
<password>notthepassword</password>
<check-valid-connection-sql>SELECT * FROM dbo.Ticket</check-valid-connection-sql>
<metadata>
<type-mapping>MS SQLSERVER</type-mapping>
</metadata>
</local-tx-datasource>
</datasources>
call entityMan.flush() or transaction.commit() befor closing it, otherwise it will discard all changes queued on close.
In the end it looks like I was using the wrong approach.... In JBoss you can`t (better said, I could not get to) access JPA directly (as you would do in JSE).
I ended creating an EJB (with transactions) and passing all JPA logic there.
PS: Of course, if I am wrong please tell me (now it is more of an academic issue, but still I want to know)

Restricting IP addresses for Jetty and Solr

I'm setting up Solr using Jetty. I would like to restrict access to only a few IP addresses. It doesn't seem immediately obvious that this can be done using Jetty. Is it possible and if so, how?
Solr 4.2.1 uses Jetty 8.1.8. Jetty 8 (as noted by jonas789) doesn't support .htaccess. Instead, it uses IPAccessHandler, which doesn't have great documentation available. I had to play with it quite a bit to get it work, so I'm posting an updated solution here.
IPAccessHandler manages a blacklist and a whitelist, accepts arbitrary ranges of IPs, and supports attaching specific URI paths to each white/black -list entry. IPAccessHandler also subclasses HandlerWrapper, which turns out to be important.
The solr app still lives in a WebAppContext (as in Lyndsay's solution), but a WebAppContext is now governed by a ContextHandler, which resides in a ContextHandlerCollection occupying the first handler slot in the server. To stop requests from the wrong IP from getting to the app, we need to wrap it inside an IPAccessHandler somewhere along that path. IPAccessHandler behaves oddly if it's in the wrong spot: I tried inserting it before the context handlers and it gave 403 Forbidden to the wrong machines, threw NullPointerException tantrums with no additional error messages, all sorts of nonsense. I finally got it to work by wrapping the ContextHandlerCollection itself, at the server level.
Go to etc/jetty.xml and scroll to the handlers section. Then wrap the existing ContextHandlerCollection item as follows:
<!-- =========================================================== -->
<!-- Set handler Collection Structure -->
<!-- =========================================================== -->
<Set name="handler">
<New id="Handlers" class="org.eclipse.jetty.server.handler.HandlerCollection">
<Set name="handlers">
<Array type="org.eclipse.jetty.server.Handler">
<Item>
<!-- here begins the new stuff -->
<New class="org.eclipse.jetty.server.handler.IPAccessHandler">
<Call name="addWhite">
<Arg>xxx.xxx.xxx.xxx</Arg>
</Call>
<Set name="handler">
<!-- here's where you put what was there before: -->
<New id="Contexts" class="org.eclipse.jetty.server.handler.ContextHandlerCollection"/>
</Set>
</New>
<!-- here ends the new stuff -->
</Item>
<Item>
<New id="DefaultHandler" class="org.eclipse.jetty.server.handler.DefaultHandler"/>
</Item>
<Item>
<New id="RequestLog" class="org.eclipse.jetty.server.handler.RequestLogHandler"/>
</Item>
</Array>
</Set>
</New>
</Set>
Resources:
http://comments.gmane.org/gmane.comp.java.jetty.support/6066
http://wiki.eclipse.org/Jetty#Configuration_Reference
http://wiki.eclipse.org/Jetty/Reference/jetty.xml_syntax
http://download.eclipse.org/jetty/stable-8/apidocs/org/eclipse/jetty/server/handler/IPAccessHandler.html
I found the solution.
Firstly, extract the contents of solr.war in the example/webapps folder.
Then create a file called .htaccess and place it in the example/webapps/solr folder (the one you just extracted) containing the following:
<Limit>
satisfy all
order deny,allow
deny from all
allow from xxx.xxx.xxx.xxx
</Limit>
In example/etc/ edit the jetty.xml file and comment out the org.mortbay.jetty.deployer.WebAppDeployer part. Then finally create a folder in example/ called contexts (if one does not yet exist) and add a file called solr.xml to it containing:
<Configure id="solr" class="org.mortbay.jetty.webapp.WebAppContext">
<Set name="resourceBase"><SystemProperty name="jetty.home" default="."/>/webapps/solr</Set>
<Set name="contextPath">/solr</Set>
<Call name="setSecurityHandler">
<Arg>
<New class="org.mortbay.jetty.security.HTAccessHandler">
<Set name="protegee">
<Ref id="solr"/>
</Set>
</New>
</Arg>
</Call>
</Configure>
Then start up your new secure solr!

How to make CXF SOAP Request to be printed under log file

#InInterceptors(interceptors = "org.apache.cxf.interceptor.LoggingInInterceptor" )
#OutInterceptors(interceptors = "org.apache.cxf.interceptor.LoggingOutInterceptor")
public class SKTWeb implements SKTWebService {
// method logic goes here
}
Hi , after adding these two lines inside the CXF Method Implementation .
I could get whip of SOAP Requestand Response under tomcat server console
see a instance of SOAP Request Printed under Tomcat console
INFO: Inbound Message
----------------------------
ID: 1
Address: /Sktweb-33.0/services/SKTWeb
Encoding: UTF-8
Content-Type: text/xml; charset=UTF-8
Headers: {cache-control=[no-cache], content-type=[text/xml; charset=UTF-8], connection=[keep-alive], host=[local
Payload: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns4:strategy xmlns:ns
Could anybody please tell me how can get this inside my Log file (Log4j)
Currently this is my log4j.properties file
log4j.rootCategory=INFO, A1
# A1 is a DailyRollingFileAppender
log4j.appender.A1=org.apache.log4j.DailyRollingFileAppender
log4j.appender.A1.file=/Haieeee.log
log4j.appender.A1.datePattern='.'yyyy-MM-dd
log4j.appender.A1.append=true
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
log4j.appender.A1.layout.ConversionPattern=%-22d{dd/MMM/yyyy HH:mm:ss} - %m%n
And also i have META-INF\cxf\org\apache\cxf\Logger Log4jLogger.class inside the Web Application .
And also i kept
<cxf:bus>
<cxf:features>
<cxf:logging/>
</cxf:features>
</cxf:bus>
Inside the endpoints.xml file
Any help please
A slight bit of confusion it seems. You need your assembled application to have a locatable file META-INF/cxf/org.apache.cxf.Logger (yes, those are dots! It's not a .java or .class file) and it should have the contents:
org.apache.cxf.common.logging.Log4jLogger
I use exactly the above in my code and it works like a charm. (I don't use it with the message logging feature though; too much traffic when deployed for my tasteā€¦)
Basically you want your properties file to be picked by CXF then it use this properties file instead of CXF's.
I am using spring configuration in my CXF application. If you are not using any Spring config then you create a new config and load it on start up using spring context listener, then you can add the below code in your XML file.
<bean id="log4jInitialization"
class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetClass" value="org.springframework.util.Log4jConfigurer" />
<property name="targetMethod" value="initLogging" />
<property name="arguments">
<list>
<value>file:fullpath/filename.properties</value>
</list>
</property>
</bean>
You can also have classpath:filename.properties in the <list> </list>. The logging implemented in Spring framework will be used to log all the request and response. You can also use the same logging implementation to use in your application.
Always go with interceptors...Add slf4j-log4j12-1.6.1.jar,slf4j-api-1.6.1.jar and commons-logging-1.1.1.jar. Paste the following code in your cxf.xml...
<bean class="org.apache.cxf.interceptor.LoggingInInterceptor" id="loggingInInterceptor" />
<bean class="org.apache.cxf.interceptor.LoggingOutInterceptor" id="logOutInterceptor" />
<cxf:bus>
<cxf:inInterceptors>
<ref bean="loggingInInterceptor" />
</cxf:inInterceptors>
<cxf:outInterceptors>
<ref bean="logOutInterceptor" />
</cxf:outInterceptors>
</cxf:bus>

Resources