/** * 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. */ package org.apache.camel.component.quickfixj.examples; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import org.apache.camel.CamelExchangeException; import org.apache.camel.Exchange; import org.apache.camel.builder.PredicateBuilder; import org.apache.camel.builder.RouteBuilder; import org.apache.camel.component.quickfixj.QuickfixjEndpoint; import org.apache.camel.component.quickfixj.QuickfixjEventCategory; import org.apache.camel.component.quickfixj.examples.util.CountDownLatchDecrementer; import org.apache.camel.impl.DefaultCamelContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import quickfix.FieldNotFound; import quickfix.Message; import quickfix.RejectLogon; import quickfix.field.MsgType; import quickfix.field.RawData; import quickfix.field.RawDataLength; /** * This example demonstrates several features of the QuickFIX/J component. It uses * QFJ session events to synchronize application behavior (e.g., Session logon). * */ public class AuthenticationExample { private static final Logger LOG = LoggerFactory.getLogger(AuthenticationExample.class); public static void main(String[] args) throws Exception { new AuthenticationExample().run(); } public void run() throws Exception { DefaultCamelContext context = new DefaultCamelContext(); final CountDownLatch logoutLatch = new CountDownLatch(1); RouteBuilder routes = new RouteBuilder() { @Override public void configure() throws Exception { // Modify the outgoing logon message to add a password // The modified message will be sent from the FIX engine when the message exchange completes from("quickfix: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")); // Release latch when the trader received a logout message from("quickfix:examples/inprocess.cfg?sessionID=FIX.4.2:TRADER->MARKET"). filter(header(QuickfixjEndpoint.EVENT_CATEGORY_KEY).isEqualTo(QuickfixjEventCategory.SessionLogoff)). bean(new CountDownLatchDecrementer("logout", logoutLatch)); // Reject all logons on market side // Demonstrates how to validate logons from("quickfix: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()); } }; context.addRoutes(routes); LOG.info("Starting Camel context"); context.start(); if (!logoutLatch.await(5L, TimeUnit.SECONDS)) { throw new IllegalStateException("Logout was not received"); } context.stop(); LOG.info("Example complete"); } public static class LogonAuthenticator { public void authenticate(Exchange exchange) throws RejectLogon, CamelExchangeException, FieldNotFound { LOG.info("Acceptor is rejecting logon for " + exchange.getIn().getHeader(QuickfixjEndpoint.SESSION_ID_KEY)); Message message = exchange.getIn().getMandatoryBody(Message.class); if (message.isSetField(RawData.FIELD)) { LOG.info("Invalid password: " + message.getString(RawData.FIELD)); } throw new RejectLogon("Rejecting logon for test purposes"); } } public static class CredentialInjector { private final String password; public CredentialInjector(String password) { this.password = password; } public void inject(Exchange exchange) throws CamelExchangeException { LOG.info("Injecting password into outgoing logon message"); Message message = exchange.getIn().getMandatoryBody(Message.class); message.setString(RawData.FIELD, password); message.setInt(RawDataLength.FIELD, password.length()); } } }