use of org.codice.ddf.admin.application.service.ApplicationNode in project ddf by codice.
the class ApplicationServiceBean method makeDependencyList.
private void makeDependencyList(List<String> childrenList, ApplicationNode application) {
LOGGER.debug("Getting Dependency List", application.getApplication().getName());
for (ApplicationNode curNode : application.getChildren()) {
Application node = curNode.getApplication();
childrenList.add(node.getName());
makeDependencyList(childrenList, curNode);
}
}
use of org.codice.ddf.admin.application.service.ApplicationNode in project ddf by codice.
the class ApplicationServiceBean method convertApplicationEntries.
private Map<String, Object> convertApplicationEntries(ApplicationNode application, List<String> parentList, List<Map<String, Object>> applicationsArray) {
LOGGER.debug("Converting {} to a map", application.getApplication().getName());
Map<String, Object> appMap = new HashMap<String, Object>();
Application internalApplication = application.getApplication();
appMap.put(MAP_NAME, internalApplication.getName());
appMap.put(MAP_VERSION, internalApplication.getVersion());
appMap.put(MAP_DESCRIPTION, internalApplication.getDescription());
appMap.put(MAP_STATE, application.getStatus().getState().toString());
appMap.put(MAP_URI, internalApplication.getURI().toString());
List<String> childrenList = new ArrayList<String>();
parentList.add(internalApplication.getName());
List<String> transferParentList = new ArrayList<String>();
appMap.put(MAP_PARENTS, parentList);
for (ApplicationNode curNode : application.getChildren()) {
Application node = curNode.getApplication();
childrenList.add(node.getName());
makeDependencyList(childrenList, curNode);
convertApplicationEntries(curNode, parentList, applicationsArray);
}
appMap.put(MAP_DEPENDENCIES, childrenList);
if (parentList.size() == 1) {
transferParentList.clear();
appMap.put(MAP_PARENTS, transferParentList);
} else {
int index = parentList.indexOf(internalApplication.getName());
for (int i = 0; i < index; i++) {
transferParentList.add(parentList.get(i));
}
appMap.put(MAP_PARENTS, transferParentList);
parentList.clear();
parentList.addAll(transferParentList);
}
applicationsArray.add(appMap);
return appMap;
}
use of org.codice.ddf.admin.application.service.ApplicationNode in project ddf by codice.
the class ApplicationServiceImpl method findCommonParent.
/**
* Finds a common parent that contains all other applications as parent
* dependencies.
*
* @param applicationSet Set of applications that should be found in a single parent.
* @param appMap Application Map containing all the application nodes.
* @return A single application that is the parent which contains all of the
* required applications as dependencies or null if no parent is
* found.
*/
private Application findCommonParent(Set<Application> applicationSet, Map<Application, ApplicationNodeImpl> appMap) {
// build dependency trees for each application in the set
Map<Application, Set<Application>> applicationTreeSet = new HashMap<Application, Set<Application>>(applicationSet.size());
for (Application curDependency : applicationSet) {
Set<Application> curDepSet = new HashSet<Application>();
curDepSet.add(curDependency);
for (ApplicationNode curParent = appMap.get(curDependency).getParent(); curParent != null; curParent = curParent.getParent()) {
curDepSet.add(curParent.getApplication());
}
applicationTreeSet.put(curDependency, curDepSet);
}
// within its parents
for (Entry<Application, Set<Application>> curAppEntry : applicationTreeSet.entrySet()) {
if (!(new HashSet<Application>(applicationSet).retainAll(curAppEntry.getValue()))) {
LOGGER.debug("{} contains all needed dependencies.", curAppEntry.getKey().getName());
return curAppEntry.getKey();
} else {
LOGGER.trace("{} does not contain all needed dependencies.", curAppEntry.getKey().getName());
}
}
return null;
}
use of org.codice.ddf.admin.application.service.ApplicationNode in project ddf by codice.
the class ApplicationServiceImpl method traverseDependencies.
/**
* Finds a parent and children dependencies for each app. Needs to be run twice
* in order to get full dependency correlations.
*
* @param appMap Application Map containing all the application nodes.
* @param filteredApplications Set containing all the application nodes minus those in the ignored list
* @param reportDebug Boolean that allows debug statements to be output or not. Only reason
* why this exists is because this function will be called twice and only
* the second set of statements will be relevant
*/
private void traverseDependencies(Map<Application, ApplicationNodeImpl> appMap, Set<Application> filteredApplications, boolean reportDebug) {
// find dependencies in each app and add them into correct node
for (Entry<Application, ApplicationNodeImpl> curAppNode : appMap.entrySet()) {
try {
// main feature will contain dependencies
Feature mainFeature = curAppNode.getKey().getMainFeature();
if (null == mainFeature) {
if (reportDebug) {
LOGGER.debug("Application \"{}\" does not contain a main feature", curAppNode.getKey().getName());
}
continue;
}
// eliminate duplications with a set
Set<Dependency> dependencies = new HashSet<>(mainFeature.getDependencies());
// remove any features that are local to the application
dependencies.removeAll(curAppNode.getKey().getFeatures());
// loop through all of the features that are left to determine
// where they are from
Set<Application> depAppSet = new HashSet<>();
for (Dependency curDepFeature : dependencies) {
Application dependencyApp = findFeature(featuresService.getFeature(curDepFeature.getName()), filteredApplications);
if (dependencyApp != null) {
if (dependencyApp.equals(curAppNode.getKey())) {
if (reportDebug) {
LOGGER.debug("Self-dependency");
}
continue;
} else {
if (reportDebug) {
LOGGER.debug("Application {} depends on the feature {} which is located in application {}.", curAppNode.getKey().getName(), curDepFeature.getName(), dependencyApp.getName());
}
depAppSet.add(dependencyApp);
}
}
}
if (!depAppSet.isEmpty()) {
Application parentApp;
if (depAppSet.size() > 1) {
parentApp = findCommonParent(depAppSet, appMap);
if (parentApp == null) {
if (reportDebug) {
LOGGER.debug("Found more than 1 application dependency for application {}. Could not determine which one is the correct parent. Application will be sent back as root application.", curAppNode.getKey().getName());
}
continue;
}
} else {
parentApp = depAppSet.iterator().next();
}
// update the dependency app with a new child
ApplicationNode parentAppNode = appMap.get(parentApp);
parentAppNode.getChildren().add(curAppNode.getValue());
curAppNode.getValue().setParent(parentAppNode);
} else {
if (reportDebug) {
LOGGER.debug("No dependency applications found for {}. This will be sent back as a root application.", curAppNode.getKey().getName());
}
}
// ApplicationServiceException from DDF and Exception from Karaf
// (FeaturesService)
} catch (Exception e) {
if (reportDebug) {
LOGGER.warn("Encountered error while determining dependencies for \"{}\". This may cause an incomplete application hierarchy to be created.", curAppNode.getKey().getName(), e);
}
}
}
}
use of org.codice.ddf.admin.application.service.ApplicationNode in project ddf by codice.
the class ApplicationServiceImplTest method testApplicationTreeWithNoMainFeature.
/**
* Test that an application tree can be created even if there is an app that
* does not contain a main feature.
*
* @throws Exception
*/
@Test
public void testApplicationTreeWithNoMainFeature() throws Exception {
Repository mainFeaturesRepo2 = createRepo(TEST_MAIN_FEATURE_2_FILE_NAME);
Set<Repository> activeRepos = new HashSet<Repository>(Arrays.asList(mainFeatureRepo, mainFeaturesRepo2, noMainFeatureRepo1));
FeaturesService featuresService = createMockFeaturesService(activeRepos, null, null);
when(bundleContext.getService(mockFeatureRef)).thenReturn(featuresService);
ApplicationService appService = createPermittedApplicationServiceImpl();
Set<ApplicationNode> rootApps = appService.getApplicationTree();
assertNotNull(rootApps);
assertEquals(2, rootApps.size());
}
Aggregations