/* * #%L * Service Locator Client for CXF * %% * Copyright (C) 2011 - 2012 Talend Inc. * %% * Licensed 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. * #L% */ package org.talend.esb.servicelocator.cxf.internal; import java.util.logging.Level; import java.util.logging.Logger; import org.apache.cxf.clustering.FailoverTargetSelector; import org.apache.cxf.message.Exchange; import org.apache.cxf.message.Message; import org.apache.cxf.service.model.EndpointInfo; import org.apache.cxf.transport.Conduit; public class LocatorTargetSelector extends FailoverTargetSelector { private static final Logger LOG = Logger .getLogger(LocatorTargetSelector.class.getPackage().getName()); private static final String LOCATOR_PROTOCOL = "locator://"; private static final String LOCATOR_SETADDRESS_FLAG = "setAddress.called"; private boolean locatorProtocol; private LocatorSelectionStrategy strategy = new DefaultSelectionStrategy(); @Override public void complete(Exchange exchange) { // This overridden method is workaround for TESB-12457 // we should have IOException in exchange header to make failover // feature works as expected // in case of TOS generated client route we get it only in message // context Message outMessage = exchange.getOutMessage(); if (outMessage != null) { Exception ex = outMessage.getContent(Exception.class); if (ex != null && exchange.get(Exception.class) == null) exchange.put(Exception.class, ex); } super.complete(exchange); } @Override public synchronized Conduit selectConduit(Message message) { setAddress(message); return super.selectConduit(message); } /* * (non-Javadoc) * * @see * org.apache.cxf.clustering.FailoverTargetSelector#prepare(org.apache.cxf * .message.Message) */ @Override public synchronized void prepare(Message message) { setAddress(message); super.prepare(message); } protected void setAddress(Message message) { if (LOG.isLoggable(Level.INFO)) { LOG.log(Level.INFO, "setAddress attempt, " + " locatorProtocol = " + locatorProtocol + " adress = " + endpoint.getEndpointInfo().getAddress() + " "); LOG.log(Level.INFO, "Using strategy " + strategy.getClass().getName() + "."); } if (message.getExchange().get(LOCATOR_SETADDRESS_FLAG) != Boolean.TRUE) { EndpointInfo ei = endpoint.getEndpointInfo(); if (locatorProtocol || ei.getAddress().startsWith(LOCATOR_PROTOCOL)) { // bug in CXF - https://issues.apache.org/jira/browse/CXF-5225 // uncomment this in case backport to version used CXF without // the fix // if (message.getExchange().getEndpoint() == null) { // message.getExchange().put(Endpoint.class, endpoint); // } if (LOG.isLoggable(Level.INFO)) { LOG.log(Level.INFO, "Found address with locator protocol, mapping it to physical address."); LOG.log(Level.INFO, "Using strategy " + strategy.getClass().getName() + "."); } String physAddress = strategy.getPrimaryAddress(message .getExchange()); if (physAddress != null) { ei.setAddress(physAddress); locatorProtocol = true; message.put(Message.ENDPOINT_ADDRESS, physAddress); if (LOG.isLoggable(Level.INFO)) { LOG.log(Level.INFO, "Physical adress " + physAddress); } } else { if (LOG.isLoggable(Level.SEVERE)) { LOG.log(Level.SEVERE, "Failed to map logical locator address to physical address."); } throw new IllegalStateException( "No endpoint found in Service Locator for service " + endpoint.getService().getName()); } } message.getExchange().put(LOCATOR_SETADDRESS_FLAG, Boolean.TRUE); } else { if (LOG.isLoggable(Level.FINE)) { LOG.log(Level.FINE, "Setting address was skipped. It was already applied for this message"); } } } public void setLocatorSelectionStrategy( LocatorSelectionStrategy locatorSelectionStrategy) { strategy = locatorSelectionStrategy; setStrategy(locatorSelectionStrategy); } }