agave-apps/apps-core/src/main/java/org/iplantc/service/apps/queue/actions/PublishAction.java
/**
     * Handles the actual record creation, cloning, and data staging of the app assets.
     * @return published software record
     * @throws SystemUnavailableException
     * @throws SystemUnknownException
     * @throws DependencyException
     *
     */
Handles the actual record creation, cloning, and data staging of the app assets.
@return published software record
@throws SystemUnavailableException
@throws SystemUnknownException
@throws DependencyException
Handles the actual record creation cloning and data staging of the app assets . @return published software record @throws SystemUnavailableException @throws SystemUnknownException @throws DependencyException
protected Software publish() 
    throws SystemUnknownException, SystemUnavailableException, DependencyException
    {
        if (getEntity().isPubliclyAvailable()) {
            throw new SoftwareException("Software is already public");
        }
        else 
        {
            File zippedFile = null;
            RemoteDataClient sourceSoftwareDataClient = null;
            RemoteDataClient publishedSoftwareDataClient = null;
            try 
            {
                publishedSoftware = getEntity().clone();
                publishedSoftware.setName(StringUtils.isEmpty(publishedSoftwareName) ? getEntity().getName() : publishedSoftwareName);
                publishedSoftware.setVersion(StringUtils.isEmpty(publishedSoftwareVersion) ? getEntity().getVersion() : publishedSoftwareVersion);
                if (StringUtils.isNotEmpty(publishedSoftwareExecutionSystemId)) 
                {
                    publishedSoftwareExecutionSystem = new SystemDao().getUserExecutionSystem(publishingUsername, publishedSoftwareExecutionSystemId);
                    if (publishedSoftwareExecutionSystem == null) {
                        throw new SystemUnknownException("No public execution system found with id " + publishedSoftwareExecutionSystemId);
                    } 
                    else if (!publishedSoftwareExecutionSystem.isPubliclyAvailable()) {
                        throw new DependencyException("The target execution system, " 
                                + publishedSoftwareExecutionSystemId 
                                + ", is not publicly available. "
                                + "Please either publish the execution system or specify another "
                                + "execution system on which the published app should run.");
                    }
                }
                else 
                {
                    if (getEntity().getExecutionSystem() == null) {
                        throw new SystemUnknownException(
                            "Please specify a public execution system on which this app should run.");
                    } 
                    else if (!getEntity().getExecutionSystem().isPubliclyAvailable()) {
                        throw new DependencyException("No public execution system was specified and "
                                + "the execution system of the original app, " 
                                + getEntity().getExecutionSystem().getSystemId() 
                                + ", is not publicly available. "
                                + "Please either publish the execution system or specify another "
                                + "execution system on which the published app should run.");
                    } 
                    else {
                        publishedSoftwareExecutionSystem = getEntity().getExecutionSystem();
                    }
                }
                publishedSoftware.setExecutionSystem(publishedSoftwareExecutionSystem);
                int latestRevision = SoftwareDao.getMaxRevisionForPublicSoftware(publishedSoftware.getName(), publishedSoftware.getVersion());
                publishedSoftware.setPubliclyAvailable(true);
                publishedSoftware.setRevisionCount(latestRevision + 1);
                sourceSoftwareDataClient = getSourceRemoteDataClient();
                StorageSystem publishedSoftwareStorageSystem = new SystemManager().getDefaultStorageSystem();
                publishedSoftwareDataClient = getDestinationRemoteDataClient(publishedSoftwareStorageSystem);
DefaultMessageBody<JsonNode> messageBody = new DefaultMessageBody<JsonNode>(
		publishedSoftware.getUuid(), TenancyHelper.getCurrentEndUser(), publishedSoftware.getTenantId(),
MessageQueueClient client = MessageClientFactory.getMessageClient();
client.push(org.iplantc.service.common.Settings.APPS_PUBLISHING_QUEUE,
		org.iplantc.service.common.Settings.APPS_PUBLISHING_QUEUE,
		messageBody.toJSON());
getEventProcessor().processSoftwareContentEvent(
		publishedSoftware, 
    		            SoftwareEventType.STAGING_QUEUED, 
    		            "Software assets from " + getEntity().getUniqueName() + " have been scheduled for publication with app.",
    		            getPublishingUsername());
                 pull the app assets and create a zip archive
                File stagedDir = fetchSoftwareDeploymentPath(sourceSoftwareDataClient);
                File tempDir = new File(Settings.TEMP_DIRECTORY);
                if (!tempDir.exists() || !tempDir.isDirectory()) {
                    tempDir.mkdirs();
                }
                zippedFile = new File(tempDir, publishedSoftware.getUniqueName() + ".zip");
                ZipUtil.zip(stagedDir, zippedFile);
                 set the checksum of the zipped archive for validation down the road.
                FileInputStream in = null;
            	try {
            		 could have been deleted from it's temp dir
            		in = new FileInputStream(zippedFile.getAbsolutePath());
            		publishedSoftware.setChecksum(DigestUtils.md5Hex(in));
            	}
            	catch (IOException e) {
            		log.error("Unable to calculate checksum of published asset for " + publishedSoftware.getUniqueName() + 
    						". None will be stored with app.", e);
            		publishedSoftware.setChecksum(null);
            	}
            	finally {
            		try { in.close(); } catch (Exception ignored){}
            	}
                 ensure the destination directory is present
                resolveAndCreatePublishedDeploymentPath(publishedSoftwareStorageSystem, publishedSoftwareDataClient); 
                copyPublicAppArchiveToDeploymentSystem(publishedSoftwareDataClient, zippedFile);
                SoftwareDao.persist(publishedSoftware);
                try {
                    FileUtils.deleteQuietly(stagedDir);
                } catch (Exception e) {
                    log.error(String.format("Failed to cleanup staging directory, %s, while publishing app %s. %s",
                            stagedDir.getAbsolutePath(), publishedSoftware.getUniqueName(), e.getMessage()));
                }
                 TODO: Make this an option through the tenant admin preferences. 
                 schedulePublicAppAssetBundleBackup();
                return publishedSoftware;
            } 
            catch (SoftwareException | DependencyException e) {
                throw e;
            } catch (Exception e)
            {
                throw new SoftwareException("Application publishing failed: " + e.getMessage(), e);
            } 
            finally 
            {
                try { if (zippedFile != null) {zippedFile.delete();} } catch (Exception ignored) {}
                try { sourceSoftwareDataClient.disconnect(); } catch (Exception ignored) {}
                try { publishedSoftwareDataClient.disconnect(); } catch (Exception ignored) {}
            }
        }
    }
protected Software publish ( ) throws SystemUnknownException , SystemUnavailableException , DependencyException { if ( getEntity ( ) . isPubliclyAvailable ( ) ) { throw new SoftwareException ( "Software is already public" ) ; } else { File zippedFile = null ; RemoteDataClient sourceSoftwareDataClient = null ; RemoteDataClient publishedSoftwareDataClient = null ; try { publishedSoftware = getEntity ( ) . clone ( ) ; publishedSoftware . setName ( StringUtils . isEmpty ( publishedSoftwareName ) ? getEntity ( ) . getName ( ) : publishedSoftwareName ) ; publishedSoftware . setVersion ( StringUtils . isEmpty ( publishedSoftwareVersion ) ? getEntity ( ) . getVersion ( ) : publishedSoftwareVersion ) ; if ( StringUtils . isNotEmpty ( publishedSoftwareExecutionSystemId ) ) { publishedSoftwareExecutionSystem = new SystemDao ( ) . getUserExecutionSystem ( publishingUsername , publishedSoftwareExecutionSystemId ) ; if ( publishedSoftwareExecutionSystem == null ) { throw new SystemUnknownException ( "No public execution system found with id " + publishedSoftwareExecutionSystemId ) ; } else if ( ! publishedSoftwareExecutionSystem . isPubliclyAvailable ( ) ) { throw new DependencyException ( "The target execution system, " + publishedSoftwareExecutionSystemId + ", is not publicly available. " + "Please either publish the execution system or specify another " + "execution system on which the published app should run." ) ; } } else { if ( getEntity ( ) . getExecutionSystem ( ) == null ) { throw new SystemUnknownException ( "Please specify a public execution system on which this app should run." ) ; } else if ( ! getEntity ( ) . getExecutionSystem ( ) . isPubliclyAvailable ( ) ) { throw new DependencyException ( "No public execution system was specified and " + "the execution system of the original app, " + getEntity ( ) . getExecutionSystem ( ) . getSystemId ( ) + ", is not publicly available. " + "Please either publish the execution system or specify another " + "execution system on which the published app should run." ) ; } else { publishedSoftwareExecutionSystem = getEntity ( ) . getExecutionSystem ( ) ; } } publishedSoftware . setExecutionSystem ( publishedSoftwareExecutionSystem ) ; int latestRevision = SoftwareDao . getMaxRevisionForPublicSoftware ( publishedSoftware . getName ( ) , publishedSoftware . getVersion ( ) ) ; publishedSoftware . setPubliclyAvailable ( true ) ; publishedSoftware . setRevisionCount ( latestRevision + 1 ) ; sourceSoftwareDataClient = getSourceRemoteDataClient ( ) ; StorageSystem publishedSoftwareStorageSystem = new SystemManager ( ) . getDefaultStorageSystem ( ) ; publishedSoftwareDataClient = getDestinationRemoteDataClient ( publishedSoftwareStorageSystem ) ; File stagedDir = fetchSoftwareDeploymentPath ( sourceSoftwareDataClient ) ; File tempDir = new File ( Settings . TEMP_DIRECTORY ) ; if ( ! tempDir . exists ( ) || ! tempDir . isDirectory ( ) ) { tempDir . mkdirs ( ) ; } zippedFile = new File ( tempDir , publishedSoftware . getUniqueName ( ) + ".zip" ) ; ZipUtil . zip ( stagedDir , zippedFile ) ; FileInputStream in = null ; try { in = new FileInputStream ( zippedFile . getAbsolutePath ( ) ) ; publishedSoftware . setChecksum ( DigestUtils . md5Hex ( in ) ) ; } catch ( IOException e ) { log . error ( "Unable to calculate checksum of published asset for " + publishedSoftware . getUniqueName ( ) + ". None will be stored with app." , e ) ; publishedSoftware . setChecksum ( null ) ; } finally { try { in . close ( ) ; } catch ( Exception ignored ) { } } resolveAndCreatePublishedDeploymentPath ( publishedSoftwareStorageSystem , publishedSoftwareDataClient ) ; copyPublicAppArchiveToDeploymentSystem ( publishedSoftwareDataClient , zippedFile ) ; SoftwareDao . persist ( publishedSoftware ) ; try { FileUtils . deleteQuietly ( stagedDir ) ; } catch ( Exception e ) { log . error ( String . format ( "Failed to cleanup staging directory, %s, while publishing app %s. %s" , stagedDir . getAbsolutePath ( ) , publishedSoftware . getUniqueName ( ) , e . getMessage ( ) ) ) ; } return publishedSoftware ; } catch ( SoftwareException | DependencyException e ) { throw e ; } catch ( Exception e ) { throw new SoftwareException ( "Application publishing failed: " + e . getMessage ( ) , e ) ; } finally { try { if ( zippedFile != null ) { zippedFile . delete ( ) ; } } catch ( Exception ignored ) { } try { sourceSoftwareDataClient . disconnect ( ) ; } catch ( Exception ignored ) { } try { publishedSoftwareDataClient . disconnect ( ) ; } catch ( Exception ignored ) { } } } }
Handles the actual record creation, cloning, and data staging of the app assets.
Handles the actual record creation cloning and data staging of the app assets .
// throw exception if the app is already public. can't republish //            File stagingDir = null; // if the user supplied an exectuion system, check that its public and valid // system does not exist // system exists, but is not public // otherwise, try the original execution system // if the system is no longer present // otherwise, if it is present, but not public // otherwise we're golden. we're using the original execution system // from the app we're publishing // TODO: This is where we could return a 201 to the user and offload the remaining  // data staging and archiving to a worker process for improved resiliency and  // greater visibility into the archiving process.  // get handles to the destination public storage system // get handles to the original software storage system // save the app //SoftwareDao.persist(publishedSoftware); //                ObjectMapper mapper = new ObjectMapper(); //                JsonNode json = mapper.createObjectNode() //                		.put("sourceAppId", super.getEntity().getUuid()) //                		.put("sourceStorageSystem", super.getEntity().getStorageSystem().getSystemId()) //                		.put("sourceDeploymentPath", super.getEntity().getDeploymentPath()) //                		.putNull("tempDir"); //                 //                DefaultMessageBody<JsonNode> messageBody = new DefaultMessageBody<JsonNode>( //                		publishedSoftware.getUuid(), TenancyHelper.getCurrentEndUser(), publishedSoftware.getTenantId(), //						json); // //                MessageQueueClient client = MessageClientFactory.getMessageClient(); //                client.push(org.iplantc.service.common.Settings.APPS_PUBLISHING_QUEUE, //                		org.iplantc.service.common.Settings.APPS_PUBLISHING_QUEUE, //                		messageBody.toJSON()); //                 //                getEventProcessor().processSoftwareContentEvent( //                		publishedSoftware,  //    		            SoftwareEventType.STAGING_QUEUED,  //    		            "Software assets from " + getEntity().getUniqueName() + " have been scheduled for publication with app.", //    		            getPublishingUsername()); // pull the app assets and create a zip archive // set the checksum of the zipped archive for validation down the road. // could have been deleted from it's temp dir // ensure the destination directory is present // save the app // TODO: Make this an option through the tenant admin preferences.  // schedulePublicAppAssetBundleBackup();