/** * 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 ddf.test.itests.platform; import static org.codice.ddf.admin.application.service.ApplicationStatus.ApplicationState.ACTIVE; import static org.codice.ddf.admin.application.service.ApplicationStatus.ApplicationState.INACTIVE; import static org.hamcrest.CoreMatchers.containsString; import static org.hamcrest.CoreMatchers.hasItem; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.not; import static org.hamcrest.Matchers.isEmptyString; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertThat; import static org.junit.Assert.fail; import java.net.URI; import java.util.List; import java.util.Set; import java.util.stream.Collectors; import org.apache.shiro.subject.Subject; import org.codice.ddf.admin.application.service.Application; import org.codice.ddf.admin.application.service.ApplicationService; import org.codice.ddf.admin.application.service.ApplicationServiceException; import org.codice.ddf.admin.application.service.ApplicationStatus; import org.codice.ddf.itests.common.AbstractIntegrationTest; import org.codice.ddf.itests.common.annotations.BeforeExam; import org.codice.ddf.itests.common.annotations.ConditionalIgnoreRule; import org.codice.ddf.itests.common.annotations.SkipUnstableTest; import org.codice.ddf.itests.common.utils.LoggingUtils; import org.codice.ddf.security.common.Security; import org.junit.FixMethodOrder; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.MethodSorters; import org.ops4j.pax.exam.junit.PaxExam; import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy; import org.ops4j.pax.exam.spi.reactors.PerSuite; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Note: Tests prefixed with aRunFirst NEED to run before any other tests. For this reason, we * use the @FixMethodOrder(MethodSorters.NAME_ASCENDING) annotation. */ @RunWith(PaxExam.class) @ExamReactorStrategy(PerSuite.class) @FixMethodOrder(MethodSorters.NAME_ASCENDING) public class TestApplicationService extends AbstractIntegrationTest { @Rule public ConditionalIgnoreRule rule = new ConditionalIgnoreRule(); private static final Logger LOGGER = LoggerFactory.getLogger(TestApplicationService.class); private static final String COMMAND_PREFIX = "app:"; private static final String START_COMMAND = COMMAND_PREFIX + "start "; private static final String STOP_COMMAND = COMMAND_PREFIX + "stop "; private static final String LIST_COMMAND = COMMAND_PREFIX + "list"; private static final String ADD_COMMAND = COMMAND_PREFIX + "add "; private static final String REMOVE_COMMAND = COMMAND_PREFIX + "remove "; private static final String STATUS_COMMAND = COMMAND_PREFIX + "status "; private static final String ACTIVE_APP = "Current State is: ACTIVE"; private static final String INACTIVE_APP = "Current State is: INACTIVE"; private static final String CATALOG_APP = "catalog-app"; //This app just needs to be one that is not started by default private static final String REGISTRY_APP = "registry-app"; private static final String SDK_APP = "sdk-app"; private static final String INACTIVE_SDK = "[INACTIVE] " + SDK_APP; private static final String APP_LIST_PROPERTIES_FILE = "/org.codice.ddf.admin.applicationlist.properties"; private static Subject systemSubject; @BeforeExam public void beforeExam() throws Exception { try { waitForSystemReady(); Security security = Security.getInstance(); systemSubject = security.runAsAdmin(security::getSystemSubject); } catch (Exception e) { LoggingUtils.failWithThrowableStacktrace(e, "Failed in @BeforeExam: "); } } @Test public void bTestAppStatus() throws ApplicationServiceException, InterruptedException { systemSubject.execute(() -> { // Test AppService ApplicationService applicationService = getServiceManager().getService( ApplicationService.class); Set<Application> apps = applicationService.getApplications(); List<Application> catalogList = apps.stream() .filter(a -> CATALOG_APP.equals(a.getName())) .collect(Collectors.toList()); if (catalogList.size() != 1) { fail("Expected to find 1 " + CATALOG_APP + " in Application list."); } Application catalog = catalogList.get(0); try { applicationService.startApplication(catalog); getServiceManager().waitForAllBundles(); } catch (ApplicationServiceException e) { LOGGER.error("Failed to start the {}: {}", CATALOG_APP, e.getMessage()); fail(); } catch (InterruptedException e) { LOGGER.error("Failed to start start all bundles {}", e.getMessage()); fail(); } assertNotNull("Application [" + CATALOG_APP + "] must not be null", catalog); ApplicationStatus status = applicationService.getApplicationStatus(catalog); assertThat("Application [" + CATALOG_APP + "] should be ACTIVE", status.getState(), is(ACTIVE)); List<Application> registryList = apps.stream() .filter(a -> REGISTRY_APP.equals(a.getName())) .collect(Collectors.toList()); if (catalogList.size() != 1) { fail("Expected to find 1 " + REGISTRY_APP + " in Application list."); } Application registry = registryList.get(0); assertNotNull("Application [" + REGISTRY_APP + "] must not be null", registry); status = applicationService.getApplicationStatus(registry); assertThat("Application [" + REGISTRY_APP + "] should be INACTIVE", status.getState(), is(INACTIVE)); // Test Commands String response = console.runCommand(STATUS_COMMAND + CATALOG_APP); assertThat(CATALOG_APP + " should be ACTIVE", response, containsString(ACTIVE_APP)); response = console.runCommand(STATUS_COMMAND + REGISTRY_APP); assertThat(REGISTRY_APP + " should be INACTIVE", response, containsString(INACTIVE_APP)); }); } @Test @ConditionalIgnoreRule.ConditionalIgnore(condition = SkipUnstableTest.class) // DDF-2954 public void cTestAppStartStop() throws ApplicationServiceException { systemSubject.execute(() -> { // Test AppService ApplicationService applicationService = getServiceManager().getService( ApplicationService.class); Application registry = applicationService.getApplication(REGISTRY_APP); assertNotNull("Application [" + REGISTRY_APP + "] must not be null", registry); ApplicationStatus status = applicationService.getApplicationStatus(registry); assertThat(REGISTRY_APP + " should be INACTIVE", status.getState(), is(INACTIVE)); try { applicationService.startApplication(registry); } catch (ApplicationServiceException e) { LOGGER.error("Failed to start the {}: {}", REGISTRY_APP, e.getMessage()); fail(); } status = applicationService.getApplicationStatus(registry); assertThat(REGISTRY_APP + " should be ACTIVE after start, but was [" + status.getState() + "]", status.getState(), is(ACTIVE)); try { applicationService.stopApplication(registry); } catch (ApplicationServiceException e) { LOGGER.error("Failed to stop the {}: {}", REGISTRY_APP, e.getMessage()); fail(); } status = applicationService.getApplicationStatus(registry); assertThat(REGISTRY_APP + " should be INACTIVE after stop", status.getState(), is(INACTIVE)); // Test Commands String response = console.runCommand(STATUS_COMMAND + REGISTRY_APP); assertThat(REGISTRY_APP + " should be INACTIVE", response, containsString(INACTIVE_APP)); response = console.runCommand(START_COMMAND + REGISTRY_APP); assertThat(REGISTRY_APP + " should be empty response after " + START_COMMAND, response, isEmptyString()); response = console.runCommand(STATUS_COMMAND + REGISTRY_APP); assertThat(REGISTRY_APP + " should be ACTIVE after " + START_COMMAND, response, containsString(ACTIVE_APP)); response = console.runCommand(STOP_COMMAND + REGISTRY_APP); assertThat(REGISTRY_APP + " should be empty response after " + START_COMMAND, response, isEmptyString()); response = console.runCommand(STATUS_COMMAND + REGISTRY_APP); assertThat(REGISTRY_APP + " should be INACTIVE after " + STOP_COMMAND, response, containsString(INACTIVE_APP)); }); } @Test public void dTestAppAddRemove() throws ApplicationServiceException { systemSubject.execute(() -> { ApplicationService applicationService = getServiceManager().getService( ApplicationService.class); Application sdkApp = applicationService.getApplication(SDK_APP); URI sdkUri = sdkApp.getURI(); // Remove try { applicationService.removeApplication(sdkApp); } catch (ApplicationServiceException e) { LOGGER.error("Failed to remove {}: {}", sdkApp.getName(), e.getMessage()); fail(); } Set<Application> apps = applicationService.getApplications(); assertThat(apps, not(hasItem(sdkApp))); // Add try { applicationService.addApplication(sdkUri); } catch (ApplicationServiceException e) { LOGGER.error("Failed to add {}: {}", sdkUri, e.getMessage()); fail(); } sdkApp = applicationService.getApplication(SDK_APP); assertThat(sdkApp.getName(), is(SDK_APP)); assertThat(sdkApp.getURI(), is(sdkUri)); ApplicationStatus status = applicationService.getApplicationStatus(sdkApp); assertThat(status.getState(), is(INACTIVE)); apps = applicationService.getApplications(); assertThat(apps, hasItem(sdkApp)); // Test Commands // Remove String response = console.runCommand(REMOVE_COMMAND + SDK_APP); assertThat("Should be empty response after " + REMOVE_COMMAND, response, isEmptyString()); response = console.runCommand(STATUS_COMMAND + SDK_APP); assertThat(SDK_APP + " should be not be found after " + REMOVE_COMMAND, response, containsString("No application found with name " + SDK_APP)); // Add response = console.runCommand(ADD_COMMAND + sdkUri.toString()); assertThat("Should be empty response after " + ADD_COMMAND, response, isEmptyString()); response = console.runCommand(STATUS_COMMAND + SDK_APP); assertThat(SDK_APP + " should be INACTIVE after " + STATUS_COMMAND, response, containsString(INACTIVE_APP)); try { applicationService.startApplication(SDK_APP); } catch (ApplicationServiceException e) { LOGGER.error("Failed to restart {}: {}", sdkUri, e.getMessage()); fail(); } }); } }