/*
* Atricore IDBus
*
* Copyright (c) 2009, Atricore Inc.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.atricore.idbus.capabilities.josso.main;
import org.apache.camel.builder.RouteBuilder;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.atricore.idbus.capabilities.josso.main.binding.JossoBinding;
import org.atricore.idbus.kernel.main.federation.metadata.EndpointDescriptor;
import org.atricore.idbus.kernel.main.federation.metadata.EndpointDescriptorImpl;
import org.atricore.idbus.kernel.main.mediation.Channel;
import org.atricore.idbus.kernel.main.mediation.IdentityMediationException;
import org.atricore.idbus.kernel.main.mediation.MessageQueueManager;
import org.atricore.idbus.kernel.main.mediation.binding.BindingChannel;
import org.atricore.idbus.kernel.main.mediation.camel.AbstractCamelMediator;
import org.atricore.idbus.kernel.main.mediation.endpoint.IdentityMediationEndpoint;
import org.atricore.idbus.kernel.main.store.SSOIdentityManager;
import org.atricore.idbus.kernel.main.util.ConfigurationContext;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
/**
* @author <a href="mailto:sgonzalez@atricore.org">Sebastian Gonzalez Oyuela</a>
* @version $Id$
* @org.apache.xbean.XBean element="binding-mediator"
*/
public class JossoMediator extends AbstractCamelMediator {
private static final Log logger = LogFactory.getLog(JossoMediator.class);
private Map<String, PartnerAppMapping> partnerAppMappings = new HashMap<String, PartnerAppMapping>();
private SSOIdentityManager identityManager;
// Some stats
private long unresolvedAssertionsCount = 0;
private long maxUnresolvedAssertionsCount = 0;
public long getMaxUnresolvedAssertionsCount() {
return maxUnresolvedAssertionsCount;
}
public void setMaxUnresolvedAssertionsCount(long maxUnresolvedAssertionsCount) {
this.maxUnresolvedAssertionsCount = maxUnresolvedAssertionsCount;
}
public long getUnresolvedAssertionsCount() {
return unresolvedAssertionsCount;
}
public void setUnresolvedAssertionsCount(long unresolvedAssertionsCount) {
this.unresolvedAssertionsCount = unresolvedAssertionsCount;
}
public void increaseUnresolvedAssertionsCount() {
unresolvedAssertionsCount ++;
}
public void decreaseUnresolvedAssertionsCount() {
unresolvedAssertionsCount --;
}
@Override
protected RouteBuilder createBindingRoutes(final BindingChannel bindingChannel) throws Exception {
// Create routes based on endpoints!
return new RouteBuilder() {
@Override
public void configure() throws Exception {
// --------------------------------------------------
// Process configured endpoints for this channel
// --------------------------------------------------
Collection<IdentityMediationEndpoint> endpoints = bindingChannel.getEndpoints();
if (endpoints == null)
throw new IdentityMediationException("No endpoints defined for bindingChannel : " + bindingChannel.getName());
for (IdentityMediationEndpoint endpoint : endpoints) {
JossoBinding binding = JossoBinding.asEnum(endpoint.getBinding());
EndpointDescriptor ed = resolveEndpoint(bindingChannel, endpoint);
switch (binding) {
// http endpoints
case SSO_ARTIFACT:
case SSO_REDIRECT:
// ----------------------------------------------------------
// HTTP Incomming messages:
// ==> josso-http ==> josso-bind ==> josso11-bind
// ----------------------------------------------------------
// FROM josso-http TO samlr2-binding (through direct component)
from("idbus-http:" + ed.getLocation()).
process(new LoggerProcessor(getLogger())).
to("direct:" + ed.getName());
// FROM samlr-bind TO josso11-bind
from("idbus-bind:camel://direct:" + ed.getName() +
"?binding=" + ed.getBinding() +
"&channelRef=" + bindingChannel.getName()).
process(new LoggerProcessor(getLogger())).
to("josso-binding:" + ed.getType() +
"?channelRef=" + bindingChannel.getName() +
"&endpointRef=" + endpoint.getName());
if (ed.getResponseLocation() != null) {
// FROM idbus-http TO samlr2-binding (through direct component)
from("idbus-http:" + ed.getResponseLocation()).
process(new LoggerProcessor(getLogger())).
to("direct:" + ed.getName() + "-response");
// FROM samlr-bind TO josso11-bind
from("idbus-bind:camel://direct:" + ed.getName() + "-response" +
"?binding=" + ed.getBinding() +
"&channelRef=" + bindingChannel.getName()).
process(new LoggerProcessor(getLogger())).
to("josso-binding:" + ed.getType() +
"?channelRef=" + bindingChannel.getName() +
"&endpointRef=" + endpoint.getName() +
"&response=true");
}
break;
case JOSSO_SOAP:
JossoService svc = JossoService.asEnum(endpoint.getType());
// ----------------------------------------------------------
// SOAP Incomming messages:
// ==> idbus-http ==> cxf ==> idbus-bind ==> josso-binding
// ----------------------------------------------------------
// FROM idbus-http TO cxf (through direct component)
from("idbus-http:" + ed.getLocation()).
process(new LoggerProcessor(getLogger())).
to("direct:" + ed.getName() + "-cxf");
// Add JAX-WS Services based on endpoint type!
switch (svc) {
case IdentityProvider:
// FROM cxf TO idbus-bind (through direct component)
from("cxf:camel://direct:" + ed.getName() + "-cxf" +
"?serviceClass=org.atricore.idbus.capabilities.josso.main.binding.services.SSOIdentityProviderImpl" +
"&serviceName={urn:org:josso:gateway:ws:1.2:wsdl}SSOIdentityProviderWS" +
"&portName={urn:org:josso:gateway:ws:1.2:wsdl}SSOIdentityProviderSoap" +
"&dataFormat=POJO").
to("direct:" + ed.getName());
break;
case IdentityManager:
// FROM cxf TO idbus-bind (through direct component)
from("cxf:camel://direct:" + ed.getName() + "-cxf" +
"?serviceClass=org.atricore.idbus.capabilities.josso.main.binding.services.SSOIdentityManagerImpl" +
"&serviceName={urn:org:josso:gateway:ws:1.2:wsdl}SSOIdentityManagerWS" +
"&portName={urn:org:josso:gateway:ws:1.2:wsdl}SSOIdentityManagerSoap" +
"&dataFormat=POJO").
to("direct:" + ed.getName());
break;
case SessionManager:
// FROM cxf TO idbus-bind (through direct component)
from("cxf:camel://direct:" + ed.getName() + "-cxf" +
"?serviceClass=org.atricore.idbus.capabilities.josso.main.binding.services.SSOSessionManagerImpl" +
"&serviceName={urn:org:josso:gateway:ws:1.2:wsdl}SSOSessionManagerWS" +
"&portName={urn:org:josso:gateway:ws:1.2:wsdl}SSOSessionManagerSoap" +
"&dataFormat=POJO").
to("direct:" + ed.getName());
break;
default:
throw new IllegalArgumentException("Unknown SOAP endpoint type : " + ed.getType());
}
// FROM samlr-bind TO josso-binding
from("idbus-bind:camel://direct:" + ed.getName() +
"?binding=" + ed.getBinding() +
"&channelRef=" + bindingChannel.getName()).
process(new LoggerProcessor(getLogger())).
to("josso-binding:" + ed.getType() +
"?channelRef=" + bindingChannel.getName() +
"&endpointRef=" + endpoint.getName());
if (ed.getResponseLocation() != null) {
// FROM idbus-http TO samlr2-binding (through direct component)
from("idbus-http:" + ed.getResponseLocation()).
process(new LoggerProcessor(getLogger())).
to("direct:" + ed.getName() + "-cxf-response");
// Add JAX-WS Services based on endpoint type!
switch (svc) {
case IdentityProvider:
// FROM cxf TO idbus-bind (through direct component)
from("cxf:camel://direct:" + ed.getName() + "-cxf-response" +
"?serviceClass=org.atricore.idbus.capabilities.josso.main.binding.services.SSOIdentityProviderImpl" +
"&serviceName={urn:org:josso:gateway:ws:1.2:wsdl}SSOIdentityProviderWS" +
"&portName={urn:org:josso:gateway:ws:1.2:wsdl}SSOIdentityProviderSoap" +
"&dataFormat=POJO").
to("direct:" + ed.getName() + "-response");
break;
case IdentityManager:
// FROM cxf TO idbus-bind (through direct component)
from("cxf:camel://direct:" + ed.getName() + "-cxf-response" +
"?serviceClass=org.atricore.idbus.capabilities.josso.main.binding.services.SSOIdentityManagerImpl" +
"&serviceName={urn:org:josso:gateway:ws:1.2:wsdl}SSOIdentityManagerWS" +
"&portName={urn:org:josso:gateway:ws:1.2:wsdl}SSOIdentityManagerSoap" +
"&dataFormat=POJO").
to("direct:" + ed.getName() + "-response");
break;
case SessionManager:
// FROM cxf TO idbus-bind (through direct component)
from("cxf:camel://direct:" + ed.getName() + "-cxf-response" +
"?serviceClass=org.atricore.idbus.capabilities.josso.main.binding.services.SSOSessionManagerImpl" +
"&serviceName={urn:org:josso:gateway:ws:1.2:wsdl}SSOSessionManagerWS" +
"&portName={urn:org:josso:gateway:ws:1.2:wsdl}SSOSessionManagerSoap" +
"&dataFormat=POJO").
to("direct:" + ed.getName() + "-response");
break;
default:
throw new IllegalArgumentException("Unknown SOAP endpoint type : " + ed.getType());
}
// FROM SAMLR2 SSOBinding TO josso-binding
from("idbus-bind:camel://" + ed.getName() + "-response" +
"?binding=" + ed.getBinding() +
"&channelRef=" + bindingChannel.getName()).
process(new LoggerProcessor(getLogger())).
to("josso-binding:" + ed.getType() +
"?channelRef=" + bindingChannel.getName() +
"&endpointRef=" + endpoint.getName() +
"&response=true");
}
break;
case SSO_LOCAL:
from("direct:" + ed.getLocation()).
to("direct:" + ed.getName() + "-local");
from("idbus-bind:camel://direct:" + ed.getName() + "-local" +
"?binding=" + ed.getBinding() +
"&channelRef=" + bindingChannel.getName()).
process(new LoggerProcessor(getLogger())).
to("josso-binding:" + ed.getType() +
"?channelRef=" + bindingChannel.getName() +
"&endpointRef=" + endpoint.getName());
default:
throw new JossoException("Unsupported JOSSO Binding " + binding.getValue());
}
}
}
};
}
public EndpointDescriptor resolveEndpoint(Channel channel, IdentityMediationEndpoint endpoint)
throws IdentityMediationException {
if (channel instanceof BindingChannel) {
String type = null;
String location;
String responseLocation;
JossoBinding binding = null;
logger.debug("Creating Endpoint Descriptor without Metadata for : " + endpoint.getName());
// ---------------------------------------------
// Resolve Endpoint binding
// ---------------------------------------------
if (endpoint.getBinding() != null)
binding = JossoBinding.asEnum(endpoint.getBinding());
else
logger.warn("No JOSSO Binding found in endpoint " + endpoint.getName());
// ---------------------------------------------
// Resolve Endpoint location
// ---------------------------------------------
location = endpoint.getLocation();
if (location.startsWith("/"))
location = channel.getLocation() + location;
// ---------------------------------------------
// Resolve Endpoint response location
// ---------------------------------------------
responseLocation = endpoint.getResponseLocation();
if (responseLocation != null && responseLocation.startsWith("/"))
responseLocation = channel.getLocation() + responseLocation;
// ---------------------------------------------
// Resolve Endpoint type
// ---------------------------------------------
// If no ':' is present, lastIndexOf should resturn -1 and the entire type is used.
type = endpoint.getType().substring(endpoint.getType().lastIndexOf("}") + 1);
return new EndpointDescriptorImpl(endpoint.getName(),
type,
binding.getValue(),
location,
responseLocation);
} else {
throw new IdentityMediationException("Unsupported channel type " +
channel.getName() + " " + channel.getClass().getName());
}
}
/**
* @return
* @org.apache.xbean.Property alias="artifact-queue-mgr"
*/
public MessageQueueManager getArtifactQueueManager() {
return super.getArtifactQueueManager();
}
public void setArtifactQueueManager(MessageQueueManager artifactQueueManager) {
super.setArtifactQueueManager(artifactQueueManager);
}
public PartnerAppMapping getPartnerAppMapping(String appId) {
PartnerAppMapping m = partnerAppMappings.get(appId);
// Add support for case insensitive searches :
if (m == null) {
for (String k : partnerAppMappings.keySet()) {
if (k.equalsIgnoreCase(appId)) {
m = partnerAppMappings.get(k);
break;
}
}
}
return m;
}
public Map<String, PartnerAppMapping> getPartnerAppMappings() {
return partnerAppMappings;
}
public void setPartnerAppMappings(Map<String, PartnerAppMapping> partnerAppMappings) {
this.partnerAppMappings = partnerAppMappings;
}
public SSOIdentityManager getIdentityManager() {
return identityManager;
}
public void setIdentityManager(SSOIdentityManager identityManager) {
this.identityManager = identityManager;
}
}