/******************************************************************************* * Copyright (c) 2006-2010 eBay Inc. All Rights Reserved. * 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 *******************************************************************************/ package org.ebayopensource.turmeric.runtime.sif.impl.handlers; import java.nio.charset.Charset; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import org.ebayopensource.turmeric.runtime.binding.utils.BindingUtils; import org.ebayopensource.turmeric.runtime.common.exceptions.ErrorDataFactory; import org.ebayopensource.turmeric.runtime.common.exceptions.ServiceException; import org.ebayopensource.turmeric.runtime.common.handler.HandlerPreconditions; import org.ebayopensource.turmeric.runtime.common.impl.handlers.BaseHandler; import org.ebayopensource.turmeric.runtime.common.pipeline.InboundMessage; import org.ebayopensource.turmeric.runtime.common.pipeline.MessageContext; import org.ebayopensource.turmeric.runtime.common.pipeline.OutboundMessage; import org.ebayopensource.turmeric.runtime.common.types.Cookie; import org.ebayopensource.turmeric.runtime.common.types.G11nOptions; import org.ebayopensource.turmeric.runtime.common.types.SOAConstants; import org.ebayopensource.turmeric.runtime.common.types.SOAHeaders; import org.ebayopensource.turmeric.runtime.errorlibrary.ErrorConstants; import org.ebayopensource.turmeric.runtime.sif.pipeline.ClientMessageContext; /** * If service is chained, this handler will copy some headers to the chained service. * * @author kmatsumoto, ichernyshev */ public class MessageContextHandler extends BaseHandler { private static final List<String> s_securityHeaders = new ArrayList<String>(); private Set<String> m_transportHeaderNames; private Set<String> m_cookieNames; private boolean m_shouldCopyUseCaseName; private boolean m_shouldCopyGlobalId; private boolean m_shouldCopyLocales; private boolean m_shouldProcessG11nOptions; private boolean m_shouldCopySecurityHeaders; @Override public void init(InitContext ctx) throws ServiceException { super.init(ctx); HandlerPreconditions.checkClientSide(ctx, this.getClass()); // Client Side Only Map<String,String> options = ctx.getOptions(); //m_contextPropertyNames = parseNameList(options, "context-properties"); List<String> cookieNames = BindingUtils.parseNameList(options, "cookies"); if (cookieNames != null) { m_cookieNames = new HashSet<String>(); for (String cookieName: cookieNames) { m_cookieNames.add(cookieName.toUpperCase()); } } m_transportHeaderNames = new HashSet<String>(); List<String> transportHeaderNames = BindingUtils.parseNameList(options, "transport-headers"); if (transportHeaderNames != null) { for (String headerName: transportHeaderNames) { headerName = SOAHeaders.normalizeName(headerName, true); if (SOAHeaders.isSOAHeader(headerName)) { // do not allow arbitrary system headers if (SOAHeaders.USECASE_NAME.equals(headerName)) { m_shouldCopyUseCaseName = true; continue; } if (SOAHeaders.GLOBAL_ID.equals(headerName)) { m_shouldCopyGlobalId = true; continue; } if (SOAHeaders.LOCALE_LIST.equals(headerName)) { m_shouldCopyLocales = true; continue; } throw new ServiceException(ErrorDataFactory.createErrorData(ErrorConstants.SVC_FACTORY_INVALID_HEADER_NAME, ErrorConstants.ERRORDOMAIN, new Object[] {ctx.getServiceId().toString(), headerName})); } m_transportHeaderNames.add(headerName); } } m_shouldCopySecurityHeaders = ("true".equalsIgnoreCase(options.get("copy-security-headers"))); // copy use case name anyways m_shouldCopyUseCaseName = true; m_shouldProcessG11nOptions = m_shouldCopyGlobalId || m_shouldCopyLocales; } @Override public void invoke(MessageContext ctx) throws ServiceException { MessageContext callerCtx = ((ClientMessageContext)ctx).getCallerMessageContext(); if (callerCtx == null) { return; //service is not chained } if (callerCtx instanceof ClientMessageContext) { return; // the caller should be not be a client message context. } boolean isRequestDirection = ctx.getProcessingStage().isRequestDirection(); MessageContext srcCtx = isRequestDirection ? callerCtx : ctx; MessageContext dstCtx = isRequestDirection ? ctx : callerCtx; OutboundMessage dstMessage = (OutboundMessage) (isRequestDirection ? dstCtx.getRequestMessage() : dstCtx.getResponseMessage()); InboundMessage srcMessage = (InboundMessage) (isRequestDirection ? srcCtx.getRequestMessage() : srcCtx.getResponseMessage()); // copy transport headers for (String name: m_transportHeaderNames) { String value = srcMessage.getTransportHeader(name); if (value != null) { dstMessage.setTransportHeader(name, value); } } //copy security headers if (m_shouldCopySecurityHeaders) { Map<String,String> headers= srcMessage.getTransportHeaders(); if (headers != null && !headers.isEmpty()) { for (Entry<String, String>entry : headers.entrySet()) { String name = entry.getKey().toUpperCase(); if (name.contains("-SECURITY-")) { String value = entry.getValue(); if (value != null && !value.isEmpty()) { dstMessage.setTransportHeader(name, value); } } } } } // copy cookies if (m_cookieNames != null) { for (String name: m_cookieNames) { Cookie cookie = srcMessage.getCookie(name); if (cookie != null) { dstMessage.setCookie(cookie); } } } // copy request ID if (dstCtx.getRequestId() == null) { String currentRequestGuid = srcCtx.getRequestGuid(); String currentRequestId = srcCtx.getRequestId(); if (currentRequestId != null || currentRequestGuid != null) { dstCtx.setRequestId(currentRequestId, currentRequestGuid); } } // copy use case info if (m_shouldCopyUseCaseName) { String useCase = srcMessage.getTransportHeader(SOAHeaders.USECASE_NAME); dstMessage.setTransportHeader(SOAHeaders.USECASE_NAME, useCase); } // copy g11sOptions if (m_shouldProcessG11nOptions) { G11nOptions srcOptions = srcMessage.getG11nOptions(); String globalId = dstMessage.getG11nOptions().getGlobalId(); if (m_shouldCopyGlobalId) { globalId = srcOptions.getGlobalId(); } List<String> locales = dstMessage.getG11nOptions().getLocales(); if (m_shouldCopyLocales) { locales = srcOptions.getLocales(); } Charset charset = dstMessage.getG11nOptions().getCharset(); dstMessage.setG11nOptions(new G11nOptions(charset, locales, globalId)); } // copy forwarded for data Object forwardedFor = srcCtx.getProperty(SOAConstants.CTX_PROP_TRANSPORT_FORWARDED_FOR); if (forwardedFor != null) { dstCtx.setProperty(SOAConstants.CTX_PROP_TRANSPORT_FORWARDED_FOR, forwardedFor); } // copy client pool name Object clientPoolName = srcCtx.getProperty(SOAConstants.CTX_PROP_CLIENT_POOL_NAME); if (clientPoolName != null) { dstCtx.setProperty(SOAConstants.CTX_PROP_CLIENT_POOL_NAME, clientPoolName); } } }