diff --git a/deployment/k8s-config/kustomize/base/skaha-workload/config/build-menu.sh b/deployment/k8s-config/kustomize/base/skaha-workload/config/build-menu.sh
index 5df3f015..57c8b749 100644
--- a/deployment/k8s-config/kustomize/base/skaha-workload/config/build-menu.sh
+++ b/deployment/k8s-config/kustomize/base/skaha-workload/config/build-menu.sh
@@ -41,6 +41,9 @@ init () {
mkdir -p ${XFCE_DESKTOP_DIR_PARENT}
ln -s ${DESKTOP_DIR} ${XFCE_DESKTOP_DIR}
fi
+
+ # sleep-forever.sh is used on desktop-app start up, refer to start-software-sh.template
+ cp /skaha-system/sleep-forever.sh ${EXECUTABLE_DIR}/.
}
build_resolution_items () {
@@ -131,11 +134,15 @@ build_menu_item () {
name=$2
category=$3
executable="${EXECUTABLE_DIR}/${name}.sh"
+ start_executable="${EXECUTABLE_DIR}/start-${name}.sh"
desktop="${DESKTOP_DIR}/${name}.desktop"
cp ${STARTUP_DIR}/software-sh.template $executable
+ cp ${STARTUP_DIR}/start-software-sh.template ${start_executable}
cp ${STARTUP_DIR}/software-category.template $desktop
sed -i -e "s#(IMAGE_ID)#${image_id}#g" $executable
sed -i -e "s#(NAME)#${name}#g" $executable
+ sed -i -e "s#(IMAGE_ID)#${image_id}#g" ${start_executable}
+ sed -i -e "s#(NAME)#${name}#g" ${start_executable}
sed -i -e "s#(NAME)#${name}#g" $desktop
sed -i -e "s#(EXECUTABLE)#${EXECUTABLE_DIR}#g" $desktop
sed -i -e "s#(CATEGORY)#${category}#g" $desktop
diff --git a/deployment/k8s-config/kustomize/base/skaha-workload/config/sleep-forever.sh b/deployment/k8s-config/kustomize/base/skaha-workload/config/sleep-forever.sh
new file mode 100755
index 00000000..5f13bbdf
--- /dev/null
+++ b/deployment/k8s-config/kustomize/base/skaha-workload/config/sleep-forever.sh
@@ -0,0 +1,5 @@
+#!/bin/bash
+# sleep forever
+while true; do
+ sleep 1000
+done
diff --git a/deployment/k8s-config/kustomize/base/skaha-workload/config/templates/software-sh.template b/deployment/k8s-config/kustomize/base/skaha-workload/config/templates/software-sh.template
index d1786634..0758abaf 100755
--- a/deployment/k8s-config/kustomize/base/skaha-workload/config/templates/software-sh.template
+++ b/deployment/k8s-config/kustomize/base/skaha-workload/config/templates/software-sh.template
@@ -1,3 +1,3 @@
#!/bin/bash
-/opt/shibboleth/bin/curl -v -L -k -E ${HOME}/.ssl/cadcproxy.pem -d "image=(IMAGE_ID)" --data-urlencode "param=(NAME)" https://${skaha_hostname}/skaha/v0/session/${VNC_PW}/app
+gnome-terminal -q --title="(NAME) launcher" -- ${HOME}/.local/skaha/bin/start-(NAME).sh
diff --git a/deployment/k8s-config/kustomize/base/skaha-workload/config/templates/start-software-sh.template b/deployment/k8s-config/kustomize/base/skaha-workload/config/templates/start-software-sh.template
new file mode 100644
index 00000000..2993f17e
--- /dev/null
+++ b/deployment/k8s-config/kustomize/base/skaha-workload/config/templates/start-software-sh.template
@@ -0,0 +1,142 @@
+#!/bin/bash
+
+handle_error() {
+ echo "$1"
+ echo "Please enter Ctl+C when you are ready to exit the xterm."
+ ${HOME}/.local/skaha/bin/sleep-forever.sh &
+ wait
+ exit 1
+}
+
+get_resource_options() {
+ resources=`curl -s -L -k -E ${HOME}/.ssl/cadcproxy.pem https://${skaha_hostname}/skaha/v0/context`
+ core_default=`echo $resources | jq .defaultCores`
+ core_options=`echo $resources | jq .availableCores[] | tr '\n' ' '`
+ ram_default=`echo $resources | jq .defaultRAM`
+ ram_options=`echo $resources | jq .availableRAM[] | tr '\n' ' '`
+}
+
+get_cores() {
+ local core_list=( ${core_options} )
+ for v in "${core_list[@]}"; do
+ local core_map[$v]=1
+ done
+
+ cores=${core_default}
+ local c=0
+ read -p "Please enter the number of cores (${core_options}) [${core_default}]: " input_cores
+ while (( c < 3 )); do
+ if [[ -z "${input_cores}" ]]; then
+ cores=${core_default}
+ echo "${cores}"
+ break
+ elif [[ -n "${core_map[${input_cores}]}" ]]; then
+ cores=${input_cores}
+ break
+ else
+ read -p "Please enter the number of cores (${core_options}) [${core_default}]: " input_cores
+ c=$(( c + 1 ))
+ fi
+ done
+
+ if (( c > 2 )); then
+ handle_error "Failed to get the number of cores from user."
+ fi
+}
+
+get_ram() {
+ local ram_list=( ${ram_options} )
+ for v in "${ram_list[@]}"; do
+ local ram_map[$v]=1
+ done
+
+ ram=${ram_default}
+ local c=0
+ read -p "Please enter the amount of memory in GB (${ram_options}) [${ram_default}]: " input_ram
+ while (( c < 3 )); do
+ if [[ -z "${input_ram}" ]]; then
+ ram=${ram_default}
+ echo "${ram}"
+ break
+ elif [[ -n "${ram_map[${input_ram}]}" ]]; then
+ ram=${input_ram}
+ break
+ else
+ read -p "Please enter the amount of memory in GB (${ram_options}) [${ram_default}]: " input_ram
+ c=$(( c + 1 ))
+ fi
+ done
+
+ if (( c > 2 )); then
+ handle_error "Failed to get the amount of ram from user."
+ fi
+}
+
+prompt_user() {
+ while true; do
+ read -p "Do you want to specify resources for (NAME)? (y/n) [n]" yn
+ if [[ -z "${yn}" || ${yn} == "n" || ${yn} == "N" ]]; then
+ echo "Launching (NAME)..."
+ app_id=`curl -s -L -k -E ${HOME}/.ssl/cadcproxy.pem -d "image=(IMAGE_ID)" --data-urlencode "param=(NAME)" https://${skaha_hostname}/skaha/v0/session/${VNC_PW}/app`
+ break
+ elif [[ ${yn} == "y" || ${yn} == "Y" ]]; then
+ get_resource_options || handle_error "Error obtaining resource defaults or options."
+ get_cores || handle_error "Error obtaining the number of cores to allocate."
+ get_ram || handle_error "Error obtaining the amount of ram to allocate."
+ echo "Launching (NAME)..."
+ app_id=`curl -s -L -k -E ${HOME}/.ssl/cadcproxy.pem -d "cores=${cores}" -d "ram=$ram" -d "image=(IMAGE_ID)" --data-urlencode "param=(NAME)" https://${skaha_hostname}/skaha/v0/session/${VNC_PW}/app`
+ break
+ else
+ echo invalid response
+ fi
+ done
+}
+
+launch_app() {
+ get_resource_options || handle_error "Error obtaining resource defaults or options."
+ prompt_user || handle_error "Error prompting user inputs."
+}
+
+get_status() {
+ curl_out=""
+ status=""
+ local n=0
+ sleep 1
+ curl_out=`curl -s -L -k -E ${HOME}/.ssl/cadcproxy.pem https://${skaha_hostname}/skaha/v0/session/${VNC_PW}/app/$1`
+ while [[ ${curl_out} != *"status"* ]]; do
+ n=$(( n + 1 ))
+ if test $n -eq 10 ; then
+ echo "Failed to get status, ${curl_out}, retrying..."
+ n=0
+ fi
+ sleep 1
+ curl_out=`curl -s -L -k -E ${HOME}/.ssl/cadcproxy.pem https://${skaha_hostname}/skaha/v0/session/${VNC_PW}/app/$1`
+ done
+}
+
+check_status() {
+ get_status $1
+ status=`echo ${curl_out} | jq .status`
+ echo "status: ${status}"
+ local count=0
+ while [[ ${status} == *"Pending"* ]]
+ do
+ count=$(( $count + 1 ))
+ get_status $1
+ status=`echo ${curl_out} | jq .status`
+ if test $count -eq 10 ; then
+ echo "status: ${status}"
+ count=0
+ fi
+ done
+
+ if [[ ${status} == *"Running"* ]]; then
+ echo "Successfully launched app."
+ sleep 1
+ else
+ handle_error "Failed to launch app, status is ${status}."
+ fi
+}
+
+launch_app
+check_status ${app_id}
diff --git a/deployment/k8s-config/kustomize/base/skaha-workload/kustomization.yaml b/deployment/k8s-config/kustomize/base/skaha-workload/kustomization.yaml
index 23e8b063..bebcc271 100644
--- a/deployment/k8s-config/kustomize/base/skaha-workload/kustomization.yaml
+++ b/deployment/k8s-config/kustomize/base/skaha-workload/kustomization.yaml
@@ -10,12 +10,14 @@ configMapGenerator:
files:
- config/start-desktop.sh
- config/build-menu.sh
+ - config/sleep-forever.sh
- name: templates
files:
- config/templates/skaha-resolutions.properties
- config/templates/xfce-directory.template
- config/templates/xfce-applications-menu-item.template
- config/templates/software-sh.template
+ - config/templates/start-software-sh.template
- config/templates/software-category.template
- config/templates/resolution-sh.template
- config/templates/resolution-desktop.template
diff --git a/deployment/k8s-config/kustomize/base/skaha/config/catalina.properties b/deployment/k8s-config/kustomize/base/skaha/config/catalina.properties
index 23c986e0..d83b1d40 100644
--- a/deployment/k8s-config/kustomize/base/skaha/config/catalina.properties
+++ b/deployment/k8s-config/kustomize/base/skaha/config/catalina.properties
@@ -5,4 +5,3 @@ ca.nrc.cadc.auth.PrincipalExtractor.enableClientCertHeader=true
ca.nrc.cadc.util.Log4jInit.messageOnly=true
# (default: ca.nrc.cadc.auth.NoOpIdentityManager)
ca.nrc.cadc.auth.IdentityManager=ca.nrc.cadc.auth.ACIdentityManager
-
diff --git a/deployment/k8s-config/kustomize/base/skaha/config/k8s-resources.properties b/deployment/k8s-config/kustomize/base/skaha/config/k8s-resources.properties
index b3815563..4d290386 100644
--- a/deployment/k8s-config/kustomize/base/skaha/config/k8s-resources.properties
+++ b/deployment/k8s-config/kustomize/base/skaha/config/k8s-resources.properties
@@ -1,13 +1,25 @@
# Defines the resources available to science containers
###
-# Default number of cores when not specified
+# Default number of requested cores when not specified
+cores-default-request = 1
+
+# Default maximum number of cores when not specified
+cores-default-limit = 16
+
+# Default number of cores (request=limit) when not specified
cores-default = 2
# Default cores for headless jobs
cores-default-headless = 1
-# Default memory (RAM) in GB when not specified
+# Default requested memory (RAM) in GB when not specified
+mem-gb-default-request = 4
+
+# Default maximum memory (RAM) in GB when not specified
+mem-gb-default-limit = 192
+
+# Default memory (RAM) in GB (request=limit) when not specified
mem-gb-default = 16
# Default RAM for headless jobs
diff --git a/deployment/k8s-config/kustomize/base/skaha/config/launch-desktop-app.yaml b/deployment/k8s-config/kustomize/base/skaha/config/launch-desktop-app.yaml
index 0c2ec565..652c8e07 100644
--- a/deployment/k8s-config/kustomize/base/skaha/config/launch-desktop-app.yaml
+++ b/deployment/k8s-config/kustomize/base/skaha/config/launch-desktop-app.yaml
@@ -4,6 +4,7 @@ kind: Job
metadata:
labels:
canfar-net-sessionID: "${skaha.sessionid}"
+ canfar-net-appID: "${software.appid}"
canfar-net-sessionType: "${skaha.sessiontype}"
canfar-net-userid: "${skaha.userid}"
name: "${software.jobname}"
@@ -14,6 +15,7 @@ spec:
metadata:
labels:
canfar-net-sessionID: "${skaha.sessionid}"
+ canfar-net-appID: "${software.appid}"
canfar-net-sessionType: "${skaha.sessiontype}"
canfar-net-userid: "${skaha.userid}"
job-name: "${software.jobname}"
@@ -51,12 +53,12 @@ spec:
imagePullPolicy: Always
resources:
requests:
- memory: "4Gi"
- cpu: "1"
+ memory: "${software.requests.ram}"
+ cpu: "${software.requests.cores}"
ephemeral-storage: "20Gi"
limits:
- memory: "192Gi"
- cpu: "16"
+ memory: "${software.limits.ram}"
+ cpu: "${software.limits.cores}"
ephemeral-storage: "200Gi"
ports:
- containerPort: 6000
diff --git a/deployment/k8s-config/kustomize/base/skaha/skaha-tomcat-deployment.yaml b/deployment/k8s-config/kustomize/base/skaha/skaha-tomcat-deployment.yaml
index 9089f0ae..d4f46b19 100644
--- a/deployment/k8s-config/kustomize/base/skaha/skaha-tomcat-deployment.yaml
+++ b/deployment/k8s-config/kustomize/base/skaha/skaha-tomcat-deployment.yaml
@@ -42,7 +42,7 @@ spec:
value: "ivo://cadc.nrc.ca/gms?skaha-users"
- name: skaha.adminsgroup
value: "ivo://cadc.nrc.ca/gms?skaha-admins"
- image: images.canfar.net/skaha-system/skaha:0.11.1
+ image: images.canfar.net/skaha-system/skaha:0.12.0
imagePullPolicy: Always
#imagePullPolicy: IfNotPresent
name: skaha-tomcat
diff --git a/deployment/k8s-config/kustomize/overlays/keel-dev/skaha/config/k8s-resources.properties b/deployment/k8s-config/kustomize/overlays/keel-dev/skaha/config/k8s-resources.properties
index a88c9827..e63b4f31 100644
--- a/deployment/k8s-config/kustomize/overlays/keel-dev/skaha/config/k8s-resources.properties
+++ b/deployment/k8s-config/kustomize/overlays/keel-dev/skaha/config/k8s-resources.properties
@@ -1,13 +1,25 @@
# Defines the resources available to science containers
###
-# Default number of cores when not specified
+# Default number of requested cores when not specified
+cores-default-request = 1
+
+# Default maximum number of cores when not specified
+cores-default-limit = 8
+
+# Default number of cores (request=limit) when not specified
cores-default = 2
# Default cores for headless jobs
cores-default-headless = 1
-# Default memory (RAM) in GB when not specified
+# Default requested memory (RAM) in GB when not specified
+mem-gb-default-request = 4
+
+# Default maximum memory (RAM) in GB when not specified
+mem-gb-default-limit = 192
+
+# Default memory (RAM) in GB (request=limit) when not specified
mem-gb-default = 16
# Default RAM for headless jobs
diff --git a/deployment/k8s-config/kustomize/overlays/keel-dev/skaha/config/launch-desktop-app.yaml b/deployment/k8s-config/kustomize/overlays/keel-dev/skaha/config/launch-desktop-app.yaml
index dfdbbc9b..65c1ac7a 100644
--- a/deployment/k8s-config/kustomize/overlays/keel-dev/skaha/config/launch-desktop-app.yaml
+++ b/deployment/k8s-config/kustomize/overlays/keel-dev/skaha/config/launch-desktop-app.yaml
@@ -4,6 +4,7 @@ kind: Job
metadata:
labels:
canfar-net-sessionID: "${skaha.sessionid}"
+ canfar-net-appID: "${software.appid}"
canfar-net-sessionType: "${skaha.sessiontype}"
canfar-net-userid: "${skaha.userid}"
name: "${software.jobname}"
@@ -14,6 +15,7 @@ spec:
metadata:
labels:
canfar-net-sessionID: "${skaha.sessionid}"
+ canfar-net-appID: "${software.appid}"
canfar-net-sessionType: "${skaha.sessiontype}"
canfar-net-userid: "${skaha.userid}"
job-name: "${software.jobname}"
@@ -51,12 +53,12 @@ spec:
imagePullPolicy: Always
resources:
requests:
- memory: "4Gi"
- cpu: "1"
+ memory: "${software.requests.ram}"
+ cpu: "${software.requests.cores}"
ephemeral-storage: "20Gi"
limits:
- memory: "192Gi"
- cpu: "8"
+ memory: "${software.limits.ram}"
+ cpu: "${software.limits.cores}"
ephemeral-storage: "200Gi"
ports:
- containerPort: 6000
diff --git a/deployment/k8s-config/kustomize/overlays/keel-dev/skaha/skaha-tomcat-deployment.yaml b/deployment/k8s-config/kustomize/overlays/keel-dev/skaha/skaha-tomcat-deployment.yaml
index 37b33a2a..c873d548 100644
--- a/deployment/k8s-config/kustomize/overlays/keel-dev/skaha/skaha-tomcat-deployment.yaml
+++ b/deployment/k8s-config/kustomize/overlays/keel-dev/skaha/skaha-tomcat-deployment.yaml
@@ -21,7 +21,7 @@ spec:
value: "345600"
- name: skaha.defaultquotagb
value: "10"
- image: images-rc.canfar.net/skaha-system/skaha:0.11.1
+ image: images-rc.canfar.net/skaha-system/skaha:0.12.0
resources:
requests:
memory: "4Gi"
diff --git a/skaha/VERSION b/skaha/VERSION
index 3d325bf3..55efecde 100644
--- a/skaha/VERSION
+++ b/skaha/VERSION
@@ -1,4 +1,4 @@
## deployable containers have a semantic and build tag
# semantic version tag: major.minor
# build version tag: timestamp
-TAGS="0.11.1 $(date -u +"%Y%m%dT%H%M%S")"
+TAGS="0.12.0 $(date -u +"%Y%m%dT%H%M%S")"
diff --git a/skaha/src/intTest/java/org/opencadc/skaha/DesktopAppLifecycleTest.java b/skaha/src/intTest/java/org/opencadc/skaha/DesktopAppLifecycleTest.java
new file mode 100644
index 00000000..99f0c30d
--- /dev/null
+++ b/skaha/src/intTest/java/org/opencadc/skaha/DesktopAppLifecycleTest.java
@@ -0,0 +1,397 @@
+/*
+ ************************************************************************
+ ******************* CANADIAN ASTRONOMY DATA CENTRE *******************
+ ************** CENTRE CANADIEN DE DONNÉES ASTRONOMIQUES **************
+ *
+ * (c) 2023. (c) 2023.
+ * Government of Canada Gouvernement du Canada
+ * National Research Council Conseil national de recherches
+ * Ottawa, Canada, K1A 0R6 Ottawa, Canada, K1A 0R6
+ * All rights reserved Tous droits réservés
+ *
+ * NRC disclaims any warranties, Le CNRC dénie toute garantie
+ * expressed, implied, or énoncée, implicite ou légale,
+ * statutory, of any kind with de quelque nature que ce
+ * respect to the software, soit, concernant le logiciel,
+ * including without limitation y compris sans restriction
+ * any warranty of merchantability toute garantie de valeur
+ * or fitness for a particular marchande ou de pertinence
+ * purpose. NRC shall not be pour un usage particulier.
+ * liable in any event for any Le CNRC ne pourra en aucun cas
+ * damages, whether direct or être tenu responsable de tout
+ * indirect, special or general, dommage, direct ou indirect,
+ * consequential or incidental, particulier ou général,
+ * arising from the use of the accessoire ou fortuit, résultant
+ * software. Neither the name de l'utilisation du logiciel. Ni
+ * of the National Research le nom du Conseil National de
+ * Council of Canada nor the Recherches du Canada ni les noms
+ * names of its contributors may de ses participants ne peuvent
+ * be used to endorse or promote être utilisés pour approuver ou
+ * products derived from this promouvoir les produits dérivés
+ * software without specific prior de ce logiciel sans autorisation
+ * written permission. préalable et particulière
+ * par écrit.
+ *
+ * This file is part of the Ce fichier fait partie du projet
+ * OpenCADC project. OpenCADC.
+ *
+ * OpenCADC is free software: OpenCADC est un logiciel libre ;
+ * you can redistribute it and/or vous pouvez le redistribuer ou le
+ * modify it under the terms of modifier suivant les termes de
+ * the GNU Affero General Public la “GNU Affero General Public
+ * License as published by the License” telle que publiée
+ * Free Software Foundation, par la Free Software Foundation
+ * either version 3 of the : soit la version 3 de cette
+ * License, or (at your option) licence, soit (à votre gré)
+ * any later version. toute version ultérieure.
+ *
+ * OpenCADC is distributed in the OpenCADC est distribué
+ * hope that it will be useful, dans l’espoir qu’il vous
+ * but WITHOUT ANY WARRANTY; sera utile, mais SANS AUCUNE
+ * without even the implied GARANTIE : sans même la garantie
+ * warranty of MERCHANTABILITY implicite de COMMERCIALISABILITÉ
+ * or FITNESS FOR A PARTICULAR ni d’ADÉQUATION À UN OBJECTIF
+ * PURPOSE. See the GNU Affero PARTICULIER. Consultez la Licence
+ * General Public License for Générale Publique GNU Affero
+ * more details. pour plus de détails.
+ *
+ * You should have received Vous devriez avoir reçu une
+ * a copy of the GNU Affero copie de la Licence Générale
+ * General Public License along Publique GNU Affero avec
+ * with OpenCADC. If not, see OpenCADC ; si ce n’est
+ * . pas le cas, consultez :
+ * .
+ *
+ ************************************************************************
+ */
+
+package org.opencadc.skaha;
+
+import ca.nrc.cadc.auth.AuthMethod;
+import ca.nrc.cadc.auth.SSLUtil;
+import ca.nrc.cadc.net.HttpDelete;
+import ca.nrc.cadc.net.HttpGet;
+import ca.nrc.cadc.net.HttpPost;
+import ca.nrc.cadc.reg.Standards;
+import ca.nrc.cadc.reg.client.RegistryClient;
+import ca.nrc.cadc.util.FileUtil;
+import ca.nrc.cadc.util.Log4jInit;
+
+import com.google.gson.Gson;
+import com.google.gson.reflect.TypeToken;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.lang.reflect.Type;
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URL;
+import java.security.PrivilegedExceptionAction;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+
+import javax.security.auth.Subject;
+
+import org.apache.log4j.Level;
+import org.apache.log4j.Logger;
+import org.junit.Assert;
+import org.junit.Test;
+import org.opencadc.skaha.session.Session;
+import org.opencadc.skaha.session.SessionAction;
+
+/**
+ * @author majorb
+ *
+ */
+public class DesktopAppLifecycleTest {
+
+ private static final Logger log = Logger.getLogger(DesktopAppLifecycleTest.class);
+ public static final URI SKAHA_SERVICE_ID = URI.create("ivo://cadc.nrc.ca/skaha");
+ public static final String PROC_SESSION_STDID = "vos://cadc.nrc.ca~vospace/CADC/std/Proc#sessions-1.0";
+ public static final String DESKTOP_IMAGE = "images-rc.canfar.net/skaha/desktop:1.0.2";
+ public static final String TERMINAL_IMAGE = "images-rc.canfar.net/skaha/terminal:1.1.2";
+
+ static {
+ Log4jInit.setLevel("org.opencadc.skaha", Level.INFO);
+ }
+
+ protected URL sessionURL;
+ protected URL desktopAppURL;
+ protected Subject userSubject;
+
+ public DesktopAppLifecycleTest() {
+ try {
+ RegistryClient regClient = new RegistryClient();
+ sessionURL = regClient.getServiceURL(SKAHA_SERVICE_ID, Standards.PROC_SESSIONS_10, AuthMethod.CERT);
+ sessionURL = new URL(sessionURL.toString() + "/session");
+ log.info("sessions URL: " + sessionURL);
+
+ File cert = FileUtil.getFileFromResource("skaha-test.pem", DesktopAppLifecycleTest.class);
+ userSubject = SSLUtil.createSubject(cert);
+ log.debug("userSubject: " + userSubject);
+ } catch (Exception e) {
+ log.error("init exception", e);
+ throw new RuntimeException("init exception", e);
+ }
+ }
+
+ @Test
+ public void testCreateDeleteDesktopApp() {
+ try {
+
+ Subject.doAs(userSubject, new PrivilegedExceptionAction