[ 
https://issues.apache.org/activemq/browse/CAMEL-1350?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=62202#action_62202
 ] 

Hadrian Zbarcea edited comment on CAMEL-1350 at 9/28/10 5:15 PM:
-----------------------------------------------------------------

Thanks for all the comments and special thanks to Hadrian for his help.

Bengt, I've been doing some experimenting and I believe the following approach 
may solve the problems you describe. If these solutions are acceptable, I'll 
submit the related modifications for inclusion in the new quickfix component 
code. The following code are snippets from a new example class that 
demonstrates logon message customization and logon authentication.

For logon message customization, I created an example bean that puts a password 
into the FIX RawData field (a common approach for older versions of the FIX 
protocol).

{code}
   public static class CredentialInjector {
        private final String password;
        
        public CredentialInjector(String password) {
            this.password = password;
        }

        public void inject(Exchange exchange) throws InvalidPayloadException {
            LOG.info("Injecting password into outgoing logon message");
            Message message = ExchangeHelper.getMandatoryInBody(exchange, 
Message.class);
            message.setString(RawData.FIELD, password);
            message.setInt(RawDataLength.FIELD, password.length());
        }
    }
{code}

I then create a route to process outgoing logon messages. (For those not 
familiar with FIX engines, the logon message is generated automatically by the 
engine but we want to modify it before it is sent.)

{code}
    from("quickfixj:examples/inprocess.cfg?sessionID=FIX.4.2:TRADER->MARKET").
        filter(PredicateBuilder.and(
            
header(QuickfixjEndpoint.EVENT_CATEGORY_KEY).isEqualTo(QuickfixjEventCategory.AdminMessageSent),
            
header(QuickfixjEndpoint.MESSAGE_TYPE_KEY).isEqualTo(MsgType.LOGON))).
        bean(new CredentialInjector("PASSWORD"));
{code}

The CredentialInjector is executing in the same thread as the toAdmin() 
callback so any modifications to the outgoing message will be in the sent 
message.

For authentication, I created a trivial and unfriendly authenticator that 
rejects all logons.

{code}
   public static class LogonAuthenticator {
        public void authenticate(Exchange exchange) throws RejectLogon, 
InvalidPayloadException, FieldNotFound {
            LOG.info("Acceptor is rejecting logon for " + 
exchange.getIn().getHeader(QuickfixjEndpoint.SESSION_ID_KEY));
            Message message = ExchangeHelper.getMandatoryInBody(exchange, 
Message.class);
            if (message.isSetField(RawData.FIELD)) {
                LOG.info("Rejected password: " + 
message.getString(RawData.FIELD));
            }
            throw new RejectLogon("Rejecting logon for test purposes");
        }
    }
{code}

Notice that it throws the RejectLogon exception which will eventually be 
propagated out of the fromAdmin() callback in the QFJ engine. The associated 
route is...

{code}
    from("quickfixj:examples/inprocess.cfg?sessionID=FIX.4.2:MARKET->TRADER").
        filter(PredicateBuilder.and(
            
header(QuickfixjEndpoint.EVENT_CATEGORY_KEY).isEqualTo(QuickfixjEventCategory.AdminMessageReceived),
            
header(QuickfixjEndpoint.MESSAGE_TYPE_KEY).isEqualTo(MsgType.LOGON))).
        bean(new LogonAuthenticator());
{code}

The example seems to be working well for both cases. Note that both scenarios 
require the Camel processor to be executing in the same thread as the QFJ 
engine. It's ok to pass messages to other threads but be sure the message is 
persisted locally first since you will not be able to rely on transport-level 
resends via FIX.

      was (Author: stevebate):
    Thanks for all the comments and special thanks to Hadrian for his help.

Bengt, I've been doing some experimenting and I believe the following approach 
may solve the problems you describe. If these solutions are acceptable, I'll 
submit the related modifications for inclusion in the new quickfix component 
code. The following code are snippets from a new example class that 
demonstrates logon message customization and logon authentication.

For logon message customization, I created an example bean that puts a password 
into the FIX RawData field (a common approach for older versions of the FIX 
protocol).

   public static class CredentialInjector {
        private final String password;
        
        public CredentialInjector(String password) {
            this.password = password;
        }

        public void inject(Exchange exchange) throws InvalidPayloadException {
            LOG.info("Injecting password into outgoing logon message");
            Message message = ExchangeHelper.getMandatoryInBody(exchange, 
Message.class);
            message.setString(RawData.FIELD, password);
            message.setInt(RawDataLength.FIELD, password.length());
        }
    }

I then create a route to process outgoing logon messages. (For those not 
familiar with FIX engines, the logon message is generated automatically by the 
engine but we want to modify it before it is sent.)

                
from("quickfixj:examples/inprocess.cfg?sessionID=FIX.4.2:TRADER->MARKET").
                    filter(PredicateBuilder.and(
                            
header(QuickfixjEndpoint.EVENT_CATEGORY_KEY).isEqualTo(QuickfixjEventCategory.AdminMessageSent),
                            
header(QuickfixjEndpoint.MESSAGE_TYPE_KEY).isEqualTo(MsgType.LOGON))).
                    bean(new CredentialInjector("PASSWORD"));

The CredentialInjector is executing in the same thread as the toAdmin() 
callback so any modifications to the outgoing message will be in the sent 
message.

For authentication, I created a trivial and unfriendly authenticator that 
rejects all logons.

   public static class LogonAuthenticator {
        public void authenticate(Exchange exchange) throws RejectLogon, 
InvalidPayloadException, FieldNotFound {
            LOG.info("Acceptor is rejecting logon for " + 
exchange.getIn().getHeader(QuickfixjEndpoint.SESSION_ID_KEY));
            Message message = ExchangeHelper.getMandatoryInBody(exchange, 
Message.class);
            if (message.isSetField(RawData.FIELD)) {
                LOG.info("Rejected password: " + 
message.getString(RawData.FIELD));
            }
            throw new RejectLogon("Rejecting logon for test purposes");
        }
    }

Notice that it throws the RejectLogon exception which will eventually be 
propagated out of the fromAdmin() callback in the QFJ engine. The associated 
route is...

                
from("quickfixj:examples/inprocess.cfg?sessionID=FIX.4.2:MARKET->TRADER").
                    filter(PredicateBuilder.and(
                            
header(QuickfixjEndpoint.EVENT_CATEGORY_KEY).isEqualTo(QuickfixjEventCategory.AdminMessageReceived),
                            
header(QuickfixjEndpoint.MESSAGE_TYPE_KEY).isEqualTo(MsgType.LOGON))).
                    bean(new LogonAuthenticator());

The example seems to be working well for both cases. Note that both scenarios 
require the Camel processor to be executing in the same thread as the QFJ 
engine. It's ok to pass messages to other threads but be sure the message is 
persisted locally first since you will not be able to rely on transport-level 
resends via FIX.
  
> camel-quickfix component in apache camel distribution
> -----------------------------------------------------
>
>                 Key: CAMEL-1350
>                 URL: https://issues.apache.org/activemq/browse/CAMEL-1350
>             Project: Apache Camel
>          Issue Type: New Feature
>         Environment:  <properties>
>               <camel-version>2.0-SNAPSHOT</camel-version>
>               <fuse-version>2.x-fuse-SNAPSHOT</fuse-version>
>               <activemq-version>5.2.0</activemq-version>
>               <quickfix-version>1.3.3</quickfix-version>
>               <mina-version>1.1.0</mina-version>
>               <slf4j-version>1.5.6</slf4j-version>
>       </properties>
>            Reporter: Charles Moulliard
>            Assignee: Hadrian Zbarcea
>             Fix For: 2.5.0
>
>         Attachments: camel-quickfix-2.zip, camel-quickfix.patch, 
> camel-quickfix.zip, camel-quickfix.zip, QuickFixDataFormat.java, 
> reportincident.quickfix.zip
>
>
> Hi,
> ATTENTION: Ignoring converter type: org.apache.camel.fix.FixConverter as a 
> dependent class could not be found: java.lang.NoClassDefFoundError: 
> biz/c24/io/api/data/DataType
> java.lang.NoClassDefFoundError: biz/c24/io/api/data/DataType
>       at java.lang.Class.getDeclaredMethods0(Native Method)
>       at java.lang.Class.privateGetDeclaredMethods(Class.java:2427)
>       at java.lang.Class.getDeclaredMethods(Class.java:1791)
>       at 
> org.apache.camel.impl.converter.AnnotationTypeConverterLoader.loadConverterMethods(AnnotationTypeConverterLoader.java:147)
>       at 
> org.apache.camel.impl.converter.AnnotationTypeConverterLoader.load(AnnotationTypeConverterLoader.java:78)
>       at 
> org.apache.camel.impl.converter.DefaultTypeConverter.checkLoaded(DefaultTypeConverter.java:260)
>       at 
> org.apache.camel.impl.converter.DefaultTypeConverter.convertTo(DefaultTypeConverter.java:95)
>       at 
> org.apache.camel.impl.converter.DefaultTypeConverter.convertTo(DefaultTypeConverter.java:71)
>       at 
> org.apache.camel.util.IntrospectionSupport.convert(IntrospectionSupport.java:263)
>       at 
> org.apache.camel.util.IntrospectionSupport.setProperty(IntrospectionSupport.java:221)
>       at 
> org.apache.camel.util.IntrospectionSupport.setProperties(IntrospectionSupport.java:188)
>       at 
> org.apache.camel.impl.DefaultComponent.setProperties(DefaultComponent.java:213)
>       at 
> org.apache.camel.component.file.GenericFileComponent.createEndpoint(GenericFileComponent.java:63)
>       at 
> org.apache.camel.component.file.GenericFileComponent.createEndpoint(GenericFileComponent.java:33)
>       at 
> org.apache.camel.impl.DefaultComponent.createEndpoint(DefaultComponent.java:81)
>       at 
> org.apache.camel.impl.DefaultCamelContext.getEndpoint(DefaultCamelContext.java:330)
>       at 
> org.apache.camel.util.CamelContextHelper.getMandatoryEndpoint(CamelContextHelper.java:54)
>       at org.apache.camel.model.RouteType.resolveEndpoint(RouteType.java:96)
>       at 
> org.apache.camel.impl.DefaultRouteContext.resolveEndpoint(DefaultRouteContext.java:106)
>       at 
> org.apache.camel.impl.DefaultRouteContext.resolveEndpoint(DefaultRouteContext.java:112)
>       at org.apache.camel.model.FromType.resolveEndpoint(FromType.java:72)
>       at 
> org.apache.camel.impl.DefaultRouteContext.getEndpoint(DefaultRouteContext.java:81)
>       at org.apache.camel.model.RouteType.addRoutes(RouteType.java:239)
>       at org.apache.camel.model.RouteType.addRoutes(RouteType.java:86)
>       at 
> org.apache.camel.impl.DefaultCamelContext.startRouteDefinitions(DefaultCamelContext.java:661)
>       at 
> org.apache.camel.impl.DefaultCamelContext.doStart(DefaultCamelContext.java:651)
>       at 
> org.apache.camel.spring.SpringCamelContext.maybeDoStart(SpringCamelContext.java:166)
>       at 
> org.apache.camel.spring.SpringCamelContext.doStart(SpringCamelContext.java:161)
>       at org.apache.camel.impl.ServiceSupport.start(ServiceSupport.java:49)
>       at 
> org.apache.camel.spring.SpringCamelContext.maybeStart(SpringCamelContext.java:96)
>       at 
> org.apache.camel.spring.SpringCamelContext.onApplicationEvent(SpringCamelContext.java:115)
>       at 
> org.springframework.context.event.SimpleApplicationEventMulticaster$1.run(SimpleApplicationEventMulticaster.java:78)
>       at 
> org.springframework.core.task.SyncTaskExecutor.execute(SyncTaskExecutor.java:49)
>       at 
> org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:76)
>       at 
> org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:274)
>       at 
> org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:736)
>       at 
> org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:383)
>       at 
> org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
>       at 
> org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:93)
>       at 
> org.apache.camel.spring.Main.createDefaultApplicationContext(Main.java:232)
>       at org.apache.camel.spring.Main.doStart(Main.java:186)
>       at org.apache.camel.impl.ServiceSupport.start(ServiceSupport.java:49)
>       at org.apache.camel.util.MainSupport.run(MainSupport.java:121)
>       at org.apache.camel.util.MainSupport.run(MainSupport.java:299)
>       at org.apache.camel.spring.Main.main(Main.java:98)
>       at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>       at 
> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
>       at 
> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
>       at java.lang.reflect.Method.invoke(Method.java:597)
>       at org.apache.camel.maven.RunMojo$1.run(RunMojo.java:396)
>       at java.lang.Thread.run(Thread.java:619)
> The org.apache.camel.fix.FixConverter class uses proprietary classes : 
> import biz.c24.io.api.data.BooleanDataType;
> import biz.c24.io.api.data.CharDataType;
> import biz.c24.io.api.data.ComplexDataObject;
> import biz.c24.io.api.data.ComplexDataType;
> import biz.c24.io.api.data.DataType;
> import biz.c24.io.api.data.DateDataType;
> import biz.c24.io.api.data.Element;
> import biz.c24.io.api.data.IntDataType;
> import biz.c24.io.api.data.NumberDataType;
> import biz.c24.io.api.data.StringDataType;
> import biz.c24.io.api.presentation.TextualSource;
> import biz.c24.io.fix42.NewOrderSingleElement;
> Except if those classes are part of open source community but How can I use 
> this component without Artix Data Service ?
> ex config :
>               <route>
>                       <from uri="fixserver:banzai-to-camel.cfg" />
>                       <to uri="log:quickfix" />
>               </route>

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.

Reply via email to