вторник, 6 декабря 2022 г.

EDMX File to XSD with XSLT

    Transform EDMX to XSD helps to resolve the observability issues. XSD allows diagram creation using several diagraming tools. Unfortunately, Dynamics  EDMX  not recognized by VS community edition. 

    What is required:

  •     Saxon , you can download it from the official web site
  •     xsl below 

     Usage

     java -jar saxon-he-11.3.jar  test.xml test.xsl -o:test.xsd

     Following xsd will be created as a result 


XSLT https://drive.google.com/file/d/1l2jCxWO9N8I0U2D52NA1T3S4SFFAXSN5/view?usp=sharing

EDMX XML example https://drive.google.com/file/d/1J5jincHIH_UAGl9ZJUW2O7c0ye9S1yuV/view?usp=sharing



понедельник, 17 июня 2013 г.

How to have two different sessions in browser for one user.

Have two different session in one browser - problematic and may be browser specific. In this case need to think how to distinguish two different tabs in browser, rather than have two different session. At this moment  i see only two valid options:

  1. generate urls with some unique id and track it as get/post parameters for each request/response. Can be easily  acheived with some web framework like Apache Wicket, where you can define/overwrite url generation strategy for whole application. 
  2. with jsf2 you can try to use view scope managed beans to track distinguish as bean property. 

четверг, 15 ноября 2012 г.

Wicket, nginx, ssl, proxy

HI there !

This post has answer to question - "How to configure reverse proxy and tomcat for Wicket application". Wicket itself has declarative instructions, what pages should be secured, and what - not. This configured via appropriate annotation @RequireHttps on page class and application configuration , like this:

final HttpsConfig httpsConfig = new HttpsConfig(

             8080,8443
            );
final HttpsMapper httpsMapper = new HttpsMapper(getRootRequestMapper(), httpsConfig);

setRootRequestMapper(httpsMapper);

//to be correct need to use 80 and 443 ports for this article


How it works - in case if page with @RequireHttps annotation is openet via not secured port, wicket send http error code 302 with url, which point  to secure url for requested page. And vise versa if not secure page opening via secure url wicket redirect to unsecure version. This sophisticated behavior not always aligned with usual web application behavior, so to support it need correct configuration on ngnix, tomcat.

Configure nginx to be an reverse proxy for apache tomcat with ssl termination very simple and fast.

First step generate certificate and key
openssl req -new -x509 -days 2000 -nodes -out cert.pem -keyout cert.key

Second step configure nginx

server {

        listen 443;

        ssl on;
        ssl_session_timeout 5m;
        ssl_protocols  SSLv3 TLSv1;
    ssl_certificate /var/cert/cert.pem;
        ssl_certificate_key /var/cert/cert.key;
        #ssl_session_cache shared:SSL:10m; #Not works in win 7
        location / {
   proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header Host $http_host;
       proxy_set_header X-Forwarded-Proto https;
            proxy_redirect off;
            proxy_connect_timeout      240;
            proxy_send_timeout         240;
            proxy_read_timeout         240;
            # note, there is not SSL here! plain HTTP is used
            proxy_pass http://localhost:8080/;
        }
     }

    server {
        listen       80;
        server_name  localhost;

        location / {
       proxy_pass http://localhost:8080/;
        }

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }

Be sure, than X-Forwarded-Proto present in your configuration in server record for 443 port

According to this configuration ssl will be terminated on ngnix and forwarded to unsecure port 8080 on tomcat, but wicket will perform check, described about and send redirect to secure url and loop will be created. To avoid redirect looping need add some configuration line to tomcat config



            unpackWARs="true" autoDeploy="true">
... skipped ...
...skipped ...

This valve analyse the X-Forwarded-Proto header, and it it set , in our case by nginx, valve set schema and secure flag in http request to https and true. 




воскресенье, 7 октября 2012 г.

Wicket behind a front-end proxy with https support


Original acrticle located here https://cwiki.apache.org/WICKET/wicket-behind-a-front-end-proxy.html but, as usual, some important parts are missing. How to support https in wicket. I`ll provide step by steps instructions with apache httpd, mod_proxy_ajp, tomcat and wicket. This was originally done for yes-cart project http://code.google.com/p/yes-cart under windows, so my local pathes are provided.

First of all need to create ssl certificate for apache httpd server, apache for windows in wamp comes with preinstalled openssl. So jump to apache bin directory and run following commands:

openssl req -new -config ../conf/openssl.cnf > yes-shop.csr
openssl rsa -in privkey.pem -out yes-shop.key
openssl x509 -in yes-shop.csr -out yes-shop.cert -req -signkey yes-shop.key -days 365

Do not forget the password.

Create folders under.
D:\dev\wamp\bin\apache\apache2.2.22\conf\extra
mkdir certs
mkdir crl
mkdir newcerts
mkdir private

Copy yes-shop.cert yes-shop.csr yes-shop.key  files from apache bin folder to certs
Copy  .rnd privkey.pem to private folder

Now lets configure ssl in apache httpd
Open D:\dev\wamp\bin\apache\apache2.2.22\conf\httpd.conf and load modules
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_ajp_module modules/mod_proxy_ajp.so
LoadModule proxy_http_module modules/mod_proxy_http.so
LoadModule ssl_module modules/mod_ssl.so

Include extra config file Include conf/extra/httpd-vhosts.conf  all my virtual hosts located here, as well as ssl instructions for this example. So edit extra/httpd-vhosts.conf  and add lines

SSLSessionCache "shmcb:D:/dev/wamp/bin/apache/apache2.2.22/logs/ssl_scache(512000)"
SSLMutex default
SSLCertificateFile "D:/dev/wamp/bin/apache/apache2.2.22/conf/extra/certs/yes-shop.cert"
SSLCertificateKeyFile "D:/dev/wamp/bin/apache/apache2.2.22/conf/extra/certs/yes-shop.key"
SSLCARevocationPath "D:/dev/wamp/bin/apache/apache2.2.22/conf/extra/crl"

Locate openssl.cnf file and edit line to
dir = D:/dev/wamp/bin/apache/apache2.2.22/conf/extra # Where everything is kept

Configure virtual hosts, so my file looks like


NameVirtualHost *:80
 
<VirtualHost *:80>
 ServerName localhost
 ProxyRequests Off
 ProxyPreserveHost On
 <Proxy *>
         Order deny,allow
         Allow from all
 </Proxy>
 ProxyPass / ajp://localhost:8009/
 ProxyPassReverse / ajp://localhost:8009/
 <Location />
         Order allow,deny
         Allow from all
 </Location>
</VirtualHost>
 
 
SSLSessionCache "shmcb:D:/dev/wamp/bin/apache/apache2.2.22/logs/ssl_scache(512000)"
SSLMutex default
SSLCertificateFile "D:/dev/wamp/bin/apache/apache2.2.22/conf/extra/certs/yes-shop.cert"
SSLCertificateKeyFile "D:/dev/wamp/bin/apache/apache2.2.22/conf/extra/certs/yes-shop.key"
SSLCARevocationPath "D:/dev/wamp/bin/apache/apache2.2.22/conf/extra/crl"
 
Listen 443
 
NameVirtualHost *:443
<VirtualHost *:443>
    SSLEngine On
    SSLCertificateFile D:/dev/wamp/bin/apache/apache2.2.22/conf/extra/certs/yes-shop.cert
    ProxyPreserveHost On
    ProxyPass / ajp://localhost:8009/
    ProxyPassReverse / ajp://localhost:8009/
</VirtualHost>
 


Configure wicket application

/**
     * {@inheritDoc}
     */
    protected void init() {
.....
            final HttpsConfig httpsConfig = new HttpsConfig(
                    80,
                    443
            );

            final HttpsMapper httpsMapper = new HttpsMapper(getRootRequestMapper(), httpsConfig);

            setRootRequestMapper(httpsMapper);
}

Tomcat configured to accept ajp connection
<Connector port="8009" enableLookups="false" protocol="AJP/1.3" redirectPort="8443" URIEncoding="UTF-8"/>

Proxy from 443 to 8443 will not work 

понедельник, 6 августа 2012 г.

XSL Grouping data for sum, avg, etc

It it easy to calculate summary values at the end of document using something like this:
<fo:table-cell border="solid 1px black" text-align="right" font-weight="bold">
    <fo:block>
        <xsl:value-of   select="format-number(sum(./yes-report/object-array/big-decimal[position() = 2]), '##0.00')"/>
    </fo:block>
</fo:table-cell>
But sometimes need to have intermediate results for some data group, for example annual monthly based sales report per each departments or payments operation via different payment gateways with different currencies. Given example point to fact, than need to have nested group. "Well know" method to acheive this - use Steve Muench method:

1. Define grouping key
<xsl:key name="currencyGroup" match="org.yes.cart.payment.persistence.entity.impl.CustomerOrderPaymentEntity"
             use="concat(orderCurrency, transactionOperation, transactionGatewayLabel)"/>
use concatination to define complex key instead one node key.

2. Add appropriate sorting
<xsl:for-each select="//org.yes.cart.payment.persistence.entity.impl.CustomerOrderPaymentEntity[generate-id(.)=generate-id(key('currencyGroup', concat(orderCurrency, transactionOperation, transactionGatewayLabel))[1])]">
     <xsl:sort select="orderCurrency"/>
     <xsl:sort select="transactionOperation"/>
     <xsl:sort select="transactionGatewayLabel"/>


3. Calculate summary at the end of each group
<xsl:if test="position() = last()">
        <fo:table-row>
            <fo:table-cell border="solid 1px black"
                           number-columns-spanned="11" font-weight="bold">
                <fo:block>Summary</fo:block>
            </fo:table-cell>
            <fo:table-cell border="solid 1px black" text-align="right"
                           font-weight="bold">
                <fo:block>
                    <xsl:value-of
                            select="format-number(sum(
                        key('currencyGroup', concat(orderCurrency, transactionOperation, transactionGatewayLabel))/paymentAmount
                        ), '##0.00')"/>
                </fo:block>
            </fo:table-cell>
        </fo:table-row>
        <fo:table-row>
            <fo:table-cell border="none"
                           number-columns-spanned="12" font-weight="bold">
                <fo:block><fo:leader /></fo:block>
            </fo:table-cell>
        </fo:table-row>
    </xsl:if>


</xsl:for-each>


Result example with xsl-fo is following:


Source files located here paymentreport.zip including xml, xslf


пятница, 27 июля 2012 г.

How to work with huge output in Jersey RESTful Web services.

How to work with huge output in Jersey RESTful Web services.
The typical usecase for Jersey + JAXB - work with whole XML document and single JAXB objects tree. But sometimes the set of objects very huge and output can not be created, because of OutOfMemoryError or other reasons. In this case need to send output as stream. Code if following:
package az.edu.hugedoc;

/**
 * User: Igor Azarny iazarny@yahoo.com
 * Date: 7/27/12
 * Time: 1:56 PM
 */

import az.edu.data.model.ObjectFactory;
import az.edu.data.model.Person;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.StreamingOutput;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;
import java.io.IOException;
import java.io.OutputStream;
import java.util.UUID;


@Path("xmlrepo")
public class HugeDocAsXmlStream {

    private ObjectFactory of;
    private Marshaller marshaller;

    public HugeDocAsXmlStream() {
        try {
            JAXBContext jc = JAXBContext.newInstance(Person.class);
            marshaller = jc.createMarshaller();
            marshaller.setProperty(Marshaller.JAXB_FRAGMENT, true);
            of = new ObjectFactory();
        } catch (JAXBException e) {
            e.printStackTrace(); // impossible
        }

    }

    @GET
    @Produces({"text/xml"})
    public StreamingOutput getHugeDocAsXmlStreamOutput() {
        return new StreamingOutput() {
            public void write(OutputStream output) throws IOException, WebApplicationException {
                XMLStreamWriter xsw = null;
                try {
                    xsw = XMLOutputFactory.newInstance().createXMLStreamWriter(output);
                    xsw.writeStartElement("personrow");

                    /**
                     *
                     * Original idea - to use hibernate scrollable result of objects.
                     *
                     * ScrollableResults results = hibernateSession.createCriteria(persistentClass.class)
                     * .setFetchSize(BATCH_SIZE)
                     * .scroll(ScrollMode.FORWARD_ONLY);
                     *
                     * while (results.next()) {
                     *     index++;
                     *     T entity = (T) results.get(0);
                     *
                     */

                    for (int i = 0; i < 1000; i++) {
                        JAXBElement<Person> personJAXBElement = of.createPerson(
                                new Person(i, "Ivan " + UUID.randomUUID().toString(), "KillTesterOff " + UUID.randomUUID().toString())
                        );
                        marshaller.marshal(personJAXBElement, xsw);
                        xsw.flush();    // Force flush the stream

                    }
                    xsw.writeEndElement();
                    xsw.writeEndDocument();
                } catch (Exception e) {
                    throw new WebApplicationException(e);
                } finally {
                    if (xsw != null) {
                        try {
                            xsw.close();
                        } catch (XMLStreamException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        };
    }

}

суббота, 21 июля 2012 г.

There will always be things that I do not understand

Code found in JAXB
/**
     * Makes sure that we are running with 2.1 JAXB API,
     * and report an error if not.
     */
    static {
        try {
            XmlSchema s = null;
            s.location();
        } catch (NullPointerException e) {
            // as epxected
        } catch (NoSuchMethodError e) {
            // this is not a 2.1 API. Where is it being loaded from?
            Messages res;
            if(XmlSchema.class.getClassLoader()==null)
                res = Messages.INCOMPATIBLE_API_VERSION_MUSTANG;
            else
                res = Messages.INCOMPATIBLE_API_VERSION;

            throw new LinkageError( res.format(
                Which.which(XmlSchema.class),
                Which.which(ModelBuilder.class)
            ));
        }
    }

суббота, 14 апреля 2012 г.

Force reindex single entity with hibernate search.

Hibernate search documentations is weak area. In case if you catch the  "IllegalStateException: Could not get property value"  try to unproxy entity.

FullTextSession fullTextSession = Search.getFullTextSession(sessionFactory.getCurrentSession());
fullTextSession.index(HibernateHelper.unproxy(entity));

пятница, 3 февраля 2012 г.

Hibernate search migration to new version.

    Have you got "SearchException: Unable to perform work. Entity Class is not @Indexed nor hosts @ContainedIn: class java.lang.String" ? I guess  yes, so try to use FieldBridge to sovle you problems with embeded indexes.

    I am migrate from 3.1.0.GA to 3.4.1.Final and collect a lot of errors. I am pretty sure, that hibernate search team dont event think about backward compatibility. Hibernate search unit test cover only simple cases , documentation is also weak.


среда, 21 декабря 2011 г.

Pay Pal

Why deside to add express to  pay pal express checkout ?
The slowest payment gateway from integration point of view. The pay pal nvp much more simply for integration.

воскресенье, 25 сентября 2011 г.

Methodology vs brain

Follow TDD, BDD, MDA, DDD, DDD again, RDD, some other driven development and simple "Hello world" become "Hell to world". So try to use your brain first.

пятница, 2 сентября 2011 г.

Write custom FaceletFactory. Returns to implementation

    The previous post was incomplete, becaue lack of time. So lets finish. Implementation of DefaultFaceletFactory in mojara jsf2 as well as the whole jsf2 not implies, that DefaultFaceletFactory may be subclassed. The set of changes from 1.x complicate sucj kind of customization - getters for compiler and cache field were removed.

    To achive desirable result and substitute the DefaultFaceletFactory with devived class need to make a small dirty hack. First of all create or use any existing reflection util to access the private field in parent class. Second subclass DefaultFaceletFactory with following constructor

public class MultiStoreFaceletFactory extends DefaultFaceletFactory {

    /**
     * Construct subclass of {@link DefaultFaceletFactory}
     * @param root  parent to decorate
     * @throws IOException  in case of error
     */
    public MultiStoreFaceletFactory(final FaceletFactory root) throws IOException {
        super(
                (Compiler) ReflUtil.getFieldValue(DefaultFaceletFactory.class, root, "compiler"),  
                ((DefaultFaceletFactory) root).getResourceResolver(),
                -1,
                (FaceletCache) ReflUtil.getFieldValue(DefaultFaceletFactory.class, root, "cache") );
        // Your code is here
    }

    // Your code is here

}

пятница, 24 июня 2011 г.

The simplicity in code much more better than complex stupidity covered by enterprise patterns.

The simplicity in code much more better than complex stupidity covered by enterprise patterns.

понедельник, 20 июня 2011 г.

Write custom FaceletFactory

It can be done via following steps:

  1.  Create class, that dirived from DefaultFaceletFactory
  2.  Overwrite logic
  3.  Configure jsf to use created class.
    <context-param>
            <param-name>com.sun.faces.faceletFactory</param-name>
            <param-value>org.yes.cart.web.application.view.MultiStoreFaceletFactory</param-value>
    </context-param>
    




воскресенье, 15 мая 2011 г.

Patch for svnwcrev

Hi there !
For people who use svnwcrev this patch http://dl.dropbox.com/u/26657232/svnwcrev-2011-05-15.diff bring necessary functionality from SubWCRev. I had a few hours to porting C code from one project to another. Nice to try again KDevelop and C. Was impressed by C APR. I hope that patch will be accepted by Oliver (maintainer of svnvcrev)
Cheers

четверг, 12 мая 2011 г.

Verbose hibernate logging

Hi there ! Do you have oververbose hibernate logging and cannot configure it via log4j.properties? If yes - try to remove slf4j-simple and your life will be more easy ... according to logging

вторник, 19 апреля 2011 г.

Dark color theme for jetbrains idea ide

Hi All !
I would like to share dark color theme for day to day  works with jetbrains idea. Tested with 8 and 10 versions on win & lin.


Download xml file from here http://dl.dropbox.com/u/26657232/dark_uptown.xml

And put it to .IntelliJIdeaXX/config/colors folder. Restart idea, open ide settings/color and fonts and select dark-uptown color scheme.

How it looks






Dark theme idea.

пятница, 15 апреля 2011 г.

A few word about jbilling - sux, sux sux.

Im pretty sure, that product can tell about self more, than i can tell about this shit. 95% classes from domain model and main services have not comments at all. But the rest have some ... Sure, this is defenetly case when better keep silence rather than comment something :) ROFL. So lets start

Two classes with name InvoiceLineDTO, both used! Perverted minds, is not it ?



    public InvoiceLineDTO(int id2, String description2, BigDecimal amount,
            BigDecimal price, BigDecimal quantity2, Integer deleted, ItemDTO item,
            Integer sourceUserId2, Integer isPercentage) {
        this.id = id2; //Wow ! 
//And Integer as flag - something crazy





OrderLineBL

/**
     * Returns an order line with everything correctly
     * initialized. It does not call plug-ins to set the price
     * @param language
     * @param userId
     * @param entityId
     * @param currencyId
     * @param precision
     * @return
     */
    public static void populateWithSimplePrice(Integer language, Integer userId,
            Integer entityId, Integer currencyId, Integer itemId, OrderLineDTO line, Integer precision) {


Constants for loosers:


public class BasicLineTotalTask extends PluggableTask implements OrderProcessingTask {


    private static final Logger LOG = Logger.getLogger(BasicLineTotalTask.class);


    public void doProcessing(OrderDTO order) throws TaskException {
        // calculations are done with 10 decimals. 
        // The final total is the rounded to 2 decimals.
        BigDecimal orderTotal = new BigDecimal("0.0000000000");
        BigDecimal taxPerTotal = new BigDecimal("0.0000000000");
        BigDecimal taxNonPerTotal = new BigDecimal("0.0000000000");
        BigDecimal nonTaxPerTotal = new BigDecimal("0.0000000000");
        BigDecimal nonTaxNonPerTotal = new BigDecimal("0.0000000000");
        


Hey !!! Jbilling devs - smudge yourself on the wall, make the world better.

And special note for people who can read this. - Никогда не пользуйтесь этим уебищным продуктом. Редкое гавно.