/**
* Copyright (c) Codice Foundation
* <p>
* 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 3 of the
* License, or any later version.
* <p>
* This program 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. A copy of the GNU Lesser General Public License
* is distributed along with this program and can be found at
* <http://www.gnu.org/licenses/lgpl.html>.
*/
package org.codice.ddf.catalog.admin.plugin;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.codice.ddf.ui.admin.api.plugin.ConfigurationAdminPlugin;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ddf.catalog.CatalogFramework;
import ddf.catalog.operation.impl.SourceInfoRequestEnterprise;
import ddf.catalog.service.ConfiguredService;
import ddf.catalog.source.CatalogProvider;
import ddf.catalog.source.FederatedSource;
import ddf.catalog.source.Source;
import ddf.catalog.source.SourceDescriptor;
import ddf.catalog.source.SourceUnavailableException;
public class SourceConfigurationAdminPlugin implements ConfigurationAdminPlugin {
private static final Logger LOGGER =
LoggerFactory.getLogger(SourceConfigurationAdminPlugin.class);
private CatalogFramework catalogFramework;
public SourceConfigurationAdminPlugin() {
}
public void init() {
}
public void destroy() {
}
public CatalogFramework getCatalogFramework() {
return catalogFramework;
}
public void setCatalogFramework(CatalogFramework catalogFramework) {
this.catalogFramework = catalogFramework;
}
/**
* Returns a map of configuration data that should be appended to the configurationDataMap
* parameter. The configurationDataMap that is passed into this function is unmodifiable and is
* passed in to simply expose what information already exists.
*
* @param configurationPid service.pid for the ConfigurationAdmin configuration
* @param configurationDataMap map of what properties have already been added to the configuration in question
* @param bundleContext used to retrieve list of services
* @return Map defining additional properties to add to the configuration
*/
@Override
public Map<String, Object> getConfigurationData(String configurationPid,
Map<String, Object> configurationDataMap, BundleContext bundleContext) {
LOGGER.debug("Obtaining configuration data for the following configuration PID: {}",
configurationPid);
Map<String, Object> statusMap = new HashMap<String, Object>();
try {
List<ServiceReference<? extends Source>> refs =
new ArrayList<ServiceReference<? extends Source>>();
refs.addAll(bundleContext.getServiceReferences(FederatedSource.class, null));
refs.addAll(bundleContext.getServiceReferences(CatalogProvider.class, null));
Set<SourceDescriptor> sources = null;
if (catalogFramework != null) {
sources = catalogFramework.getSourceInfo(new SourceInfoRequestEnterprise(true))
.getSourceInfo();
}
boolean foundSources = CollectionUtils.isNotEmpty(sources);
for (ServiceReference<? extends Source> ref : refs) {
Source superService = bundleContext.getService(ref);
if (superService instanceof ConfiguredService) {
ConfiguredService cs = (ConfiguredService) superService;
LOGGER.debug("ConfiguredService configuration PID: {}",
cs.getConfigurationPid());
boolean csConfigPidMatchesTargetPid = false;
if (StringUtils.isNotEmpty(cs.getConfigurationPid()) && cs.getConfigurationPid()
.equals(configurationPid)) {
csConfigPidMatchesTargetPid = true;
}
if (foundSources) {
// If the configured service pid does not match, for now
// we're just going to assume that the metatype pid is
// the same as the class because we have no other way to
// match these things up. Obviously, this won't always
// be the case and this isn't necessarily a good way to
// do this. However, at the moment, there doesn't seem
// to be any other way to match up this metatype pid
// (which is what it ends up being in the case of a
// ManagedService) with the actual service that gets
// created. If, as in the Solr Catalog Provider case,
// the metatype pid is actually the fully qualified
// class name, then we can match them up this way.
if (csConfigPidMatchesTargetPid || cs.getClass()
.getCanonicalName()
.equals(configurationPid)) {
for (SourceDescriptor descriptor : sources) {
if (descriptor.getSourceId()
.equals(superService.getId())) {
statusMap.put("available", descriptor.isAvailable());
statusMap.put("sourceId", descriptor.getSourceId());
return statusMap;
}
}
}
} else if (csConfigPidMatchesTargetPid) {
// we don't want to call isAvailable because that can
// potentially block execution but if for some reason we
// have no catalog framework, just hit the source
// directly
statusMap.put("available", superService.isAvailable());
return statusMap;
}
}
}
} catch (org.osgi.framework.InvalidSyntaxException ise) {
// this should never happen because the filter is always null
LOGGER.debug("Error reading LDAP service filter", ise);
} catch (SourceUnavailableException sue) {
LOGGER.info("Unable to retrieve sources from Catalog Framework", sue);
}
return statusMap;
}
}