/* ############################################################################### # # # Copyright (C) 2011-2016 OpenMEAP, Inc. # # Credits to Jonathan Schang & Rob Thacher # # # # Released under the LGPLv3 # # # # OpenMEAP 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 # # (at your option) any later version. # # # # OpenMEAP 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 OpenMEAP. If not, see <http://www.gnu.org/licenses/>. # # # ############################################################################### */ package com.openmeap.admin.web; import java.io.File; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import com.openmeap.thirdparty.org.json.me.JSONObject; import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.openmeap.constants.FormConstants; import com.openmeap.http.HttpHeader; import com.openmeap.http.HttpResponse; import com.openmeap.json.JSONObjectBuilder; import com.openmeap.model.ModelManager; import com.openmeap.model.dto.Application; import com.openmeap.model.dto.ApplicationVersion; import com.openmeap.model.dto.ClusterNode; import com.openmeap.model.dto.Deployment; import com.openmeap.model.dto.GlobalSettings; import com.openmeap.protocol.dto.ConnectionOpenResponse; import com.openmeap.protocol.dto.Result; import com.openmeap.protocol.dto.UpdateHeader; import com.openmeap.util.AuthTokenProvider; import com.openmeap.util.Utils; /** * Performs an end-to-end test of the administrative console functionality. * As the admin panel grows, we'll need to split this up into separate tests. * * Note that the order of tests in this class is significant. * * @author Schang */ public class AdminTest { final static private String APP_NAME = "OpenMEAP Development Application"; final static private String APP_DESC = "This application has been created programmatically in order to test the functions of the administrative console"; final static private Integer APP_DEPL_LEN = 10; final static private String APP_ADMINS = "default-admin"; final static private String APP_VERSION_ADMINS = "default-versioner"; final static private String APP_ADDMODIFY_SUCCESS = "Application successfully created/modified!"; final static private String VERSION_ORIG = "initialVersionId"; final static private String VERSION_01 = "version01Id"; final static private String VERSION_01_ZIP = "version01.zip"; final static private String VERSION_01_HASH = "08c7f5cb8486466b872aac2059cd47f4"; final static private String VERSION_01_NOTES = "Test notes - version01"; final static private Long VERSION_01_UNCOMPRESSED_BYTES_LENGTH = 1776L; final static private Long VERSION_01_BYTES_LENGTH = 686L; final static private String VERSION_02 = "version02Id"; final static private String VERSION_02_ZIP = "version02.zip"; final static private String VERSION_02_HASH = "d2ed29ae33e7ddf9ff99fa9b6ad0724d"; final static private String VERSION_02_NOTES = "Test notes - version02"; final static private Long VERSION_02_UNCOMPRESSED_BYTES_LENGTH = 1776L; final static private Long VERSION_02_BYTES_LENGTH = 686L; final static private String SLIC_VERSION = "0.0.1a"; static private AdminTestHelper helper; static private ModelManager modelManager; static private Logger logger = LoggerFactory.getLogger(AdminTest.class); @BeforeClass static public void beforeClass() { org.apache.log4j.BasicConfigurator.configure(); helper = new AdminTestHelper(); modelManager = helper.getModelManager(); } @Test public void adminTest() throws Exception { testLogin(); testUpdateGlobalSettings(); testAddApplication(); testModifyApplication(); testCreateApplicationVersion(); testDeleteApplicationVersion(); testUpdateApplicationVersion(); testCreateDeployments(); testDeleteApplication(); } public void testLogin() throws Exception { HttpResponse response = helper.getLogin(); Utils.consumeInputStream(response.getResponseBody()); response = helper.postLogin(AdminTestHelper.ADMIN_USER, AdminTestHelper.ADMIN_PASS); Assert.assertTrue(response.getStatusCode()==302); HttpHeader[] headers = response.getHeaders("Location"); Assert.assertTrue(headers.length==1); Assert.assertTrue(headers[0].getValue().equals(helper.getAdminUrl())); Utils.consumeInputStream(response.getResponseBody()); // Tomcat will shoot you in the face if you don't follow it's redirects response = helper.getRequestExecuter().get(headers[0].getValue()); Utils.consumeInputStream(response.getResponseBody()); } public void testUpdateGlobalSettings() throws Exception { // correct location of storage path prefix GlobalSettings originalSettings = new GlobalSettings(); originalSettings.setExternalServiceUrlPrefix(AdminTestHelper.SERVICES_WEB_URL); originalSettings.setMaxFileUploadSize(1234550); originalSettings.setServiceManagementAuthSalt(AdminTestHelper.SERVICES_WEB_AUTH_SALT); originalSettings.setTemporaryStoragePath(AdminTestHelper.ADMIN_WEB_STORAGE); // correct cluster node location and path prefix ClusterNode node = new ClusterNode(); node.setServiceWebUrlPrefix(AdminTestHelper.NODE_01_SERVICES_URL); node.setFileSystemStoragePathPrefix(AdminTestHelper.NODE_01_STORAGE); originalSettings.addClusterNode(node); // validate settings stored in database String returnBody = Utils.readInputStream(helper.postGlobalSettings(originalSettings).getResponseBody(),FormConstants.CHAR_ENC_DEFAULT); logger.info(returnBody); modelManager.getModelService().clearPersistenceContext(); GlobalSettings insertedSettings = modelManager.getGlobalSettings(); JSONObjectBuilder job = new JSONObjectBuilder(); String originalSettingsJSON = job.toJSON(originalSettings).toString(3); String insertedSettingsJSON = job.toJSON(insertedSettings).toString(3); logger.info("original: {}",originalSettingsJSON); logger.info("inserted: {}",insertedSettingsJSON); Assert.assertEquals(originalSettingsJSON,insertedSettingsJSON); } public void testAddApplication() throws Exception { Application app = new Application(); app.setName(APP_NAME); app.setDescription(APP_DESC); app.setDeploymentHistoryLength(APP_DEPL_LEN); app.setVersionAdmins(APP_VERSION_ADMINS); app.setAdmins(APP_ADMINS); app.setInitialVersionIdentifier(VERSION_ORIG); HttpResponse response = helper.postAddModifyApp(app); Assert.assertTrue(response.getStatusCode()==200); String output = Utils.readInputStream(response.getResponseBody(),FormConstants.CHAR_ENC_DEFAULT); Assert.assertTrue(output.contains(APP_ADDMODIFY_SUCCESS)); // Now check the database, to make sure everything got in there Application dbApp = modelManager.getModelService().findApplicationByName(APP_NAME); Assert.assertTrue(dbApp!=null); helper.assertSame(app,dbApp); Assert.assertTrue(dbApp.getProxyAuthSalt()!=null && dbApp.getProxyAuthSalt().length()==36); } public void testModifyApplication() throws Exception { Application dbApp = modelManager.getModelService().findApplicationByName(APP_NAME); Assert.assertTrue(dbApp!=null); // make some changes String newDesc = "Creating a new description"; Integer newLen = 2; dbApp.setDescription(newDesc); dbApp.setDeploymentHistoryLength(newLen); Utils.consumeInputStream(helper.postAddModifyApp(dbApp).getResponseBody()); // validate changes modelManager.refresh(dbApp,null); Assert.assertTrue(dbApp.getDescription().equals(newDesc)); Assert.assertTrue(dbApp.getDeploymentHistoryLength().equals(newLen)); // TODO: validate changes are reflected by services-web, from the refresh hit } public void testCreateApplicationVersion() throws Exception { _createApplicationVersion(VERSION_01,VERSION_01_NOTES,VERSION_01_ZIP,VERSION_01_HASH); _createApplicationVersion(VERSION_02,VERSION_02_NOTES,VERSION_02_ZIP,VERSION_02_HASH); } public void testDeleteApplicationVersion() throws Exception { Assert.assertTrue("if no other version shares the archive, then the archive file should be deleted",_deleteApplicationVersion(VERSION_01)); // recreate version01, except with the archive used by version02 // validate that the archive from version01 is deleted _createApplicationVersion(VERSION_01,VERSION_01_NOTES,VERSION_02_ZIP,VERSION_02_HASH); Assert.assertTrue("if another version shares the archive, then leave it there",!_deleteApplicationVersion(VERSION_01)); // restore original version01 // validates that the archive from version01 is recreated _createApplicationVersion(VERSION_01,VERSION_01_NOTES,VERSION_01_ZIP,VERSION_01_HASH); } public void testUpdateApplicationVersion() throws Exception { GlobalSettings settings = modelManager.getGlobalSettings(); // validate that an unused archive is deleted // update version update // and that it is recreated when reuploaded ApplicationVersion version1 = modelManager.getModelService().findAppVersionByNameAndId(APP_NAME, VERSION_01); String response = Utils.readInputStream( helper.postAddModifyAppVer(version1, new File(this.getClass().getResource(VERSION_02_ZIP).getFile())).getResponseBody(), FormConstants.CHAR_ENC_DEFAULT ); modelManager.getModelService().clearPersistenceContext(); version1 = modelManager.getModelService().findAppVersionByNameAndId(APP_NAME, VERSION_01); ApplicationVersion version2 = modelManager.getModelService().findAppVersionByNameAndId(APP_NAME, VERSION_01); Assert.assertTrue(version1.getArchive().getHash().equals(VERSION_02_HASH)); Assert.assertTrue(version2.getArchive().getHash().equals(VERSION_02_HASH)); Assert.assertSame(version2.getArchive(),version1.getArchive()); // now restore the archive of version1 // and validate that version2's archive is not erroneously updated. response = Utils.readInputStream( helper.postAddModifyAppVer(version1, new File(this.getClass().getResource(VERSION_01_ZIP).getFile())).getResponseBody(), FormConstants.CHAR_ENC_DEFAULT ); modelManager.getModelService().clearPersistenceContext(); version1 = modelManager.getModelService().findAppVersionByNameAndId(APP_NAME, VERSION_01); version2 = modelManager.getModelService().findAppVersionByNameAndId(APP_NAME, VERSION_02); Assert.assertTrue(version1.getArchive().getHash().equals(VERSION_01_HASH)); Assert.assertTrue(version1.getArchive().getFile(settings.getTemporaryStoragePath()).exists()); Assert.assertTrue(version2.getArchive().getHash().equals(VERSION_02_HASH)); Assert.assertTrue(version2.getArchive().getFile(settings.getTemporaryStoragePath()).exists()); Assert.assertNotSame(version2.getArchive(),version1.getArchive()); Result result = helper.getConnectionOpen(version1,SLIC_VERSION); Assert.assertTrue(result.getConnectionOpenResponse().getUpdate()==null); Assert.assertTrue(AuthTokenProvider.validateAuthToken( version1.getApplication().getProxyAuthSalt(), result.getConnectionOpenResponse().getAuthToken())); } public void testCreateDeployments() throws Exception { Result result = null; ApplicationVersion version1 = modelManager.getModelService().findAppVersionByNameAndId(APP_NAME, VERSION_01); ApplicationVersion version2 = modelManager.getModelService().findAppVersionByNameAndId(APP_NAME, VERSION_02); UpdateHeader update = null; _createDeployment(VERSION_01,Deployment.Type.IMMEDIATE); modelManager.getModelService().clearPersistenceContext(); Application app = modelManager.getModelService().findApplicationByName(APP_NAME); Assert.assertTrue(app.getDeployments().size()==1); result = helper.getConnectionOpen(version2,SLIC_VERSION); update = result.getConnectionOpenResponse().getUpdate(); Assert.assertTrue(update.getType().value().equals(Deployment.Type.IMMEDIATE.name())); Assert.assertTrue(update.getVersionIdentifier().equals(VERSION_01)); Assert.assertTrue(update.getHash().getValue().equals(VERSION_01_HASH)); Assert.assertTrue(update.getStorageNeeds().equals(VERSION_01_UNCOMPRESSED_BYTES_LENGTH)); Assert.assertTrue( update.getInstallNeeds().equals( VERSION_01_UNCOMPRESSED_BYTES_LENGTH + VERSION_01_BYTES_LENGTH)); _createDeployment(VERSION_02,Deployment.Type.REQUIRED); modelManager.getModelService().clearPersistenceContext(); app = modelManager.getModelService().findApplicationByName(APP_NAME); Assert.assertTrue(app.getDeployments().size()==2); result = helper.getConnectionOpen(version1,SLIC_VERSION); update = result.getConnectionOpenResponse().getUpdate(); Assert.assertTrue(update.getType().value().equals(Deployment.Type.REQUIRED.name())); Assert.assertTrue(update.getVersionIdentifier().equals(VERSION_02)); Assert.assertTrue(update.getHash().getValue().equals(VERSION_02_HASH)); Assert.assertTrue(update.getStorageNeeds().equals(VERSION_02_UNCOMPRESSED_BYTES_LENGTH)); Assert.assertTrue( update.getInstallNeeds().equals( VERSION_02_UNCOMPRESSED_BYTES_LENGTH + VERSION_02_BYTES_LENGTH)); _createDeployment(VERSION_02,Deployment.Type.REQUIRED); Assert.assertTrue("as this deployment is created, the archive for version01 should be removed from the deployed location", !_isVersionArchiveInDeployedLocation(VERSION_01_HASH)); _createDeployment(VERSION_01,Deployment.Type.IMMEDIATE); Assert.assertTrue("as this deployment is created, the archive for version01 should be in the deployed location", _isVersionArchiveInDeployedLocation(VERSION_01_HASH)); result = helper.getConnectionOpen(version2,SLIC_VERSION); update = result.getConnectionOpenResponse().getUpdate(); Assert.assertTrue(update.getType().value().equals(Deployment.Type.IMMEDIATE.name())); Assert.assertTrue(update.getVersionIdentifier().equals(VERSION_01)); Assert.assertTrue(update.getHash().getValue().equals(VERSION_01_HASH)); Assert.assertTrue(update.getStorageNeeds().equals(VERSION_01_UNCOMPRESSED_BYTES_LENGTH)); Assert.assertTrue( update.getInstallNeeds().equals( VERSION_01_UNCOMPRESSED_BYTES_LENGTH + VERSION_01_BYTES_LENGTH)); modelManager.getModelService().clearPersistenceContext(); app = modelManager.getModelService().findApplicationByName(APP_NAME); Assert.assertTrue(app.getDeployments().size()==2); Assert.assertTrue(app.getDeployments().get(0).getVersionIdentifier().equals(VERSION_02)); Assert.assertTrue(app.getDeployments().get(1).getVersionIdentifier().equals(VERSION_01)); } public void testDeleteApplication() throws Exception { ModelManager modelManager = helper.getModelManager(); Application dbApp = modelManager.getModelService().findApplicationByName(APP_NAME); HttpResponse response = helper.postAddModifyApp_delete(dbApp); modelManager.getModelService().clearPersistenceContext(); dbApp = modelManager.getModelService().findApplicationByName(APP_NAME); Assert.assertTrue(dbApp==null); Assert.assertTrue(!_isVersionArchiveInAdminLocation(VERSION_01_HASH)); Assert.assertTrue(!_isVersionArchiveInAdminLocation(VERSION_02_HASH)); Assert.assertTrue(!_isVersionArchiveInDeployedLocation(VERSION_01_HASH)); Assert.assertTrue(!_isVersionArchiveInDeployedLocation(VERSION_02_HASH)); } /* * PRIVATE HELPER METHODS */ private void _createApplicationVersion(String identifier, String notes, String archiveName, String hash) throws Exception { Application app = modelManager.getModelService().findApplicationByName(APP_NAME); ApplicationVersion version = new ApplicationVersion(); version.setIdentifier(identifier); version.setNotes(notes); app.addVersion(version); File uploadArchive = new File(this.getClass().getResource(archiveName).getFile()); Utils.consumeInputStream(helper.postAddModifyAppVer(version, uploadArchive).getResponseBody()); // archive is uploaded modelManager.getModelService().clearPersistenceContext(); app = modelManager.getModelService().findApplicationByName(APP_NAME); version = app.getVersions().get(identifier); Assert.assertTrue(version!=null); // validate that the archive was uploaded and exploded Assert.assertTrue(_isVersionArchiveInAdminLocation(hash)); } /** * * @param identifier * @return true if archive deleted * @throws Exception */ private Boolean _deleteApplicationVersion(String identifier) throws Exception { ApplicationVersion version = modelManager.getModelService().findAppVersionByNameAndId(APP_NAME, identifier); String hash = version.getArchive().getHash(); Utils.consumeInputStream(helper.postAddModifyAppVer_delete(version).getResponseBody()); modelManager.getModelService().clearPersistenceContext(); version = modelManager.getModelService().findAppVersionByNameAndId(APP_NAME, identifier); Assert.assertTrue(version==null); return !_isVersionArchiveInAdminLocation(hash); } private void _createDeployment(String identifier, Deployment.Type type) throws Exception { modelManager.getModelService().clearPersistenceContext(); ApplicationVersion version = modelManager.getModelService().findAppVersionByNameAndId(APP_NAME, identifier); String body = Utils.readInputStream(helper.postCreateDeployment(version, type).getResponseBody(),FormConstants.CHAR_ENC_DEFAULT); logger.info(body); Assert.assertTrue(_isVersionArchiveInDeployedLocation(version.getArchive().getHash())); } private Boolean _isVersionArchiveInAdminLocation(String hash) { File verAr = new File(AdminTestHelper.ADMIN_WEB_STORAGE+"/"+hash); File verAr2 = new File(AdminTestHelper.ADMIN_WEB_STORAGE+"/"+hash+".zip"); return verAr2.exists() && verAr2.isFile() && verAr.exists() && verAr.isDirectory(); } private Boolean _isVersionArchiveInDeployedLocation(String hash) { File verAr = new File(AdminTestHelper.NODE_01_STORAGE+"/"+hash+".zip"); return verAr.exists() && verAr.isFile(); } }