| /** |
| * 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.cxf.dosgi.dsw.handlers; |
| |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.Collection; |
| import java.util.Collections; |
| import java.util.HashSet; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Set; |
| |
| import org.apache.cxf.dosgi.dsw.Constants; |
| import org.apache.cxf.dosgi.dsw.api.DistributionProvider; |
| import org.apache.cxf.dosgi.dsw.api.Endpoint; |
| import org.apache.cxf.dosgi.dsw.api.IntentUnsatisfiedException; |
| import org.apache.cxf.dosgi.dsw.qos.IntentManager; |
| import org.apache.cxf.dosgi.dsw.util.OsgiUtils; |
| import org.apache.cxf.dosgi.dsw.util.StringPlus; |
| import org.osgi.framework.BundleContext; |
| import org.osgi.framework.ServiceReference; |
| import org.osgi.service.remoteserviceadmin.EndpointDescription; |
| import org.osgi.service.remoteserviceadmin.RemoteConstants; |
| import org.slf4j.Logger; |
| import org.slf4j.LoggerFactory; |
| |
| public class CXFDistributionProvider implements DistributionProvider { |
| |
| protected static final String DEFAULT_CONFIGURATION_TYPE = Constants.WS_CONFIG_TYPE; |
| private static final Logger LOG = LoggerFactory.getLogger(CXFDistributionProvider.class); |
| |
| // protected because of tests |
| protected final String[] supportedConfigurationTypes; |
| |
| private IntentManager intentManager; |
| private PojoConfigurationTypeHandler pojoConfigurationTypeHandler; |
| private JaxRSPojoConfigurationTypeHandler jaxRsPojoConfigurationTypeHandler; |
| private WsdlConfigurationTypeHandler wsdlConfigurationTypeHandler; |
| private Set<String> configTypesSet; |
| |
| public CXFDistributionProvider(BundleContext bc, IntentManager intentManager, |
| HttpServiceManager httpServiceManager) { |
| this.intentManager = intentManager; |
| this.pojoConfigurationTypeHandler = new PojoConfigurationTypeHandler(bc, intentManager, httpServiceManager); |
| this.jaxRsPojoConfigurationTypeHandler = new JaxRSPojoConfigurationTypeHandler(bc, |
| intentManager, |
| httpServiceManager); |
| this.wsdlConfigurationTypeHandler = new WsdlConfigurationTypeHandler(bc, intentManager, httpServiceManager); |
| supportedConfigurationTypes = new String[] {Constants.WS_CONFIG_TYPE, |
| Constants.WSDL_CONFIG_TYPE, |
| Constants.RS_CONFIG_TYPE, |
| Constants.WS_CONFIG_TYPE_OLD}; |
| configTypesSet = new HashSet<>(Arrays.asList(supportedConfigurationTypes)); |
| } |
| |
| @Override |
| public Endpoint exportService(ServiceReference<?> sref, Map<String, Object> effectiveProperties, |
| String exportedInterface) { |
| List<String> configurationTypes = determineConfigurationTypes(effectiveProperties); |
| DistributionProvider handler = getHandler(configurationTypes, effectiveProperties); |
| return handler != null ? handler.exportService(sref, effectiveProperties, exportedInterface) : null; |
| } |
| |
| @Override |
| public Object importEndpoint(BundleContext consumerContext, Class<?> iClass, EndpointDescription endpoint) |
| throws IntentUnsatisfiedException { |
| List<String> configurationTypes = determineConfigTypesForImport(endpoint); |
| DistributionProvider handler = getHandler(configurationTypes, endpoint.getProperties()); |
| return handler != null ? handler.importEndpoint(consumerContext, iClass, endpoint) : null; |
| } |
| |
| DistributionProvider getHandler(List<String> configurationTypes, |
| Map<String, Object> serviceProperties) { |
| intentManager.assertAllIntentsSupported(serviceProperties); |
| if (configurationTypes.contains(Constants.WS_CONFIG_TYPE) |
| || configurationTypes.contains(Constants.WS_CONFIG_TYPE_OLD) |
| || configurationTypes.contains(Constants.RS_CONFIG_TYPE)) { |
| boolean jaxrs = isJaxrsRequested(configurationTypes, serviceProperties); |
| return jaxrs ? jaxRsPojoConfigurationTypeHandler : pojoConfigurationTypeHandler; |
| } else if (configurationTypes.contains(Constants.WSDL_CONFIG_TYPE)) { |
| return wsdlConfigurationTypeHandler; |
| } |
| LOG.info("None of the configuration types in " + configurationTypes + " is supported."); |
| return null; |
| } |
| |
| private boolean isJaxrsRequested(Collection<String> types, Map<String, Object> serviceProperties) { |
| if (types == null) { |
| return false; |
| } |
| |
| if (types.contains(Constants.RS_CONFIG_TYPE)) { |
| Collection<String> intentsProperty |
| = OsgiUtils.getMultiValueProperty(serviceProperties.get(RemoteConstants.SERVICE_EXPORTED_INTENTS)); |
| boolean hasHttpIntent = false; |
| boolean hasSoapIntent = false; |
| if (intentsProperty != null) { |
| for (String intent : intentsProperty) { |
| if (intent.contains("SOAP")) { |
| hasSoapIntent = true; |
| break; |
| } |
| |
| if (intent.contains("HTTP")) { |
| hasHttpIntent = true; |
| } |
| } |
| } |
| if ((hasHttpIntent && !hasSoapIntent) || intentsProperty == null) { |
| return true; |
| } |
| } |
| return false; |
| } |
| |
| /** |
| * determine which configuration types should be used / if the requested are |
| * supported |
| */ |
| List<String> determineConfigurationTypes(Map<String, Object> serviceProperties) { |
| String[] requestedConfigurationTypes = StringPlus.normalize(serviceProperties |
| .get(RemoteConstants.SERVICE_EXPORTED_CONFIGS)); |
| if (requestedConfigurationTypes == null || requestedConfigurationTypes.length == 0) { |
| return Collections.singletonList(DEFAULT_CONFIGURATION_TYPE); |
| } |
| |
| List<String> configurationTypes = new ArrayList<String>(); |
| for (String rct : requestedConfigurationTypes) { |
| if (configTypesSet.contains(rct)) { |
| configurationTypes.add(rct); |
| } |
| } |
| LOG.info("Configuration types selected for export: {}.", configurationTypes); |
| return configurationTypes; |
| } |
| |
| private List<String> determineConfigTypesForImport(EndpointDescription endpoint) { |
| List<String> remoteConfigurationTypes = endpoint.getConfigurationTypes(); |
| |
| List<String> usableConfigurationTypes = new ArrayList<String>(); |
| for (String ct : supportedConfigurationTypes) { |
| if (remoteConfigurationTypes.contains(ct)) { |
| usableConfigurationTypes.add(ct); |
| } |
| } |
| |
| LOG.info("Ignoring endpoint {} as it has no compatible configuration types: {}.", |
| endpoint.getId(), remoteConfigurationTypes); |
| return usableConfigurationTypes; |
| } |
| |
| public String[] getSupportedTypes() { |
| return supportedConfigurationTypes; |
| } |
| |
| } |