long start()

in uima-ducc-sm/src/main/java/org/apache/uima/ducc/sm/ServiceInstance.java [204:347]


    long start(DuccProperties svc_props, DuccProperties meta_props)
    {
    	String methodName = "start";

        logger.info(methodName, sset.getId(), "START INSTANCE");
        setStopped(false);
        this.user = meta_props.getProperty(IStateServices.SvcMetaProps.user.pname());

        // Simple use of ducc_ling, just submit as the user.  The specification will have the working directory
        // and classpath needed for the service, handled by the Orchestrator and Job Driver.
        String[] args = genArgs(svc_props);

        for ( int i = 0; i < args.length; i++ ) {
            if ( i > 0 && (args[i-1].equals("-cp") ) ) {
                // The classpaths can be just awful filling the logs with junk.  It will end up in the agent log
                // anyway so let's inhibit it here.
                logger.debug(methodName, sset.getId(), "Args[", i, "]: <CLASSPATH>");
            } else {
                logger.debug(methodName, sset.getId(), "Args[", i, "]:", args[i]);
            }
        }

        ProcessBuilder pb = new ProcessBuilder(args);
        StdioListener sin_listener = null;
        StdioListener ser_listener = null;

        Map<String, String> env = pb.environment();
        env.put(IDuccUser.EnvironmentVariable.DUCC_HOME.value(), System.getProperty(IDuccUser.EnvironmentVariable.DUCC_HOME.value()));
        env.put(IDuccUser.EnvironmentVariable.DUCC_ID_SERVICE.value(), Integer.toString(instance_id));  // UIMA-4258
        // for runmode = Test
        String runmode = DuccPropertiesResolver.get(DuccPropertiesResolver.ducc_runmode);
		if(runmode != null) {
			if(runmode.equals("Test")) {
				env.put(IDuccUser.EnvironmentVariable.USER.value(), this.user);
			}
		}
        // Extract the DUCC_UMASK setting and put it ducc_ling's environment UIMA-5328
        // Could use QuotedOprtions to build a map but since we want just one ...
        //        ArrayList<String> envVarList = QuotedOptions.tokenizeList(environment, true);
        final String umaskKey = "DUCC_UMASK";
        String envValue = svc_props.getProperty(IStateServices.SvcRegProps.environment.pname());
        if (envValue != null) {
            List<String> envList = Arrays.asList(envValue.split("\\s+"));   // No need to strip quotes ... !?
            Map<String, String> envMap = QuotedOptions.parseAssignments(envList, 0);
            String umask = envMap.get(umaskKey);
            if (umask != null) {
                env.put(umaskKey, umask);
            }
        }

		try {
			Process p = pb.start();

			InputStream stdout = p.getInputStream();
			InputStream stderr = p.getErrorStream();

            sin_listener = new StdioListener(1, stdout);
            ser_listener = new StdioListener(2, stderr);
            Thread sol = new Thread(sin_listener);
            Thread sel = new Thread(ser_listener);
            sol.start();
            sel.start();

            int rc = p.waitFor();
            logger.debug(methodName, null, "DuccServiceSubmit returns with rc", rc);

            sin_listener.stop();
            ser_listener.stop();
		} catch (Throwable t) {
            logger.error(methodName, sset.getId(), t);
            try {
                sset.setErrorString(t.toString());
            } catch ( Exception e ) {
                logger.warn(methodName, sset.getId(), "Error updating meta properties:", e);
            }
            return -1;
		}

        for ( String s : stderr_lines ) {
            logger.info(methodName, sset.getId(), "Start stderr:", s);
        }

        // That was annoying.  Now search the lines for some hint of the id.
        boolean inhibit_cp = false;
        boolean started = false;
        StringBuffer submit_buffer = new StringBuffer();
        boolean recording = false;
        for ( String s : stdout_lines ) {

            // simple logic to inhibit printing the danged classpath
            if ( inhibit_cp ) {
                inhibit_cp = false;
                logger.info(methodName, sset.getId(), "<INHIBITED CP>");
            } else {
                logger.info(methodName, sset.getId(), "Start stdout:", s);
            }

            if ( s.indexOf("-cp") >= 0 ) {
                inhibit_cp = true;
            }

            if ( recording ) {
                submit_buffer.append(s.trim());
                submit_buffer.append(";");
            }
            if ( s.startsWith("1001 Command launching...") ) {
                recording = true;
                continue;
            }

            // e.g. Service instance 18803 submitted
            if ( s.startsWith("Service") && s.endsWith("submitted") ) {
                String[] toks = s.split("\\s");
                try {
                    numeric_id = Long.parseLong(toks[2]);
                    started = true;
                    logger.info(methodName, null, "Request to start service " + sset.getId().toString() + " accepted as service instance ", numeric_id);
                } catch ( NumberFormatException e ) {
                    try {
                        sset.setErrorString("Request to start service " + sset.getId().toString() + " failed, can't interpret submit response.: " + s);
                    } catch ( Exception ee ) {
                        logger.warn(methodName, sset.getId(), "Error updating meta properties:", ee);
                    }
                    logger.warn(methodName, null,  "Request to start service " + sset.getId().toString() + " failed, can't interpret response.: " + s);
                }

            }
        }

        if ( ! started ) {
            logger.warn(methodName, sset.getId(), "Request to start service " + sset.getId().toString() + " failed.");
            meta_props.put(IStateServices.SvcMetaProps.submit_error.pname(), submit_buffer.toString());
            sset.log_errors(stdout_lines, stderr_lines);
        } else {
            meta_props.remove(IStateServices.SvcMetaProps.submit_error.pname());
            state = JobState.Received;
        }
        logger.info(methodName, sset.getId(), "START INSTANCE COMPLETE");

        stdout_lines.clear();
        stderr_lines.clear();

        return numeric_id;
    }