@Override
    public Integer call() throws Exception {
        if (!CommandUtil.isInputValid(this)) {
            return ToolConstants.INVALID_INPUT_ERROR_CODE;
        }

        if(!StringUtils.isEmpty(structuredOutput)){
            WorkflowLogger.setDisabled(true);
            verbose=false;
        }

        // Validate Service specs with schema
        if (!serviceSpecInputValidator.validate(serviceSpecsFiles)) {
            if(WorkflowLogger.isDisabled()){
                outputHandler.generateErrorMessage(WorkflowConstants.DEPLOYMENT_ERROR);
            }
            return ToolConstants.INVALID_INPUT_ERROR_CODE;
        }

        Map<String, File> serviceVsSpecFile = new HashMap<>();
        for (File serviceSpec : serviceSpecsFiles) {
            serviceVsSpecFile.put(ServiceSpecUtil.getServiceName(serviceSpec), serviceSpec);
        }

        // Process servicespecs to form EffectiveServiceSpec from ProfileArg & ServiceSpecFiles
        List<EffectiveServiceSpec> effectiveServiceSpecs;
        try {
            effectiveServiceSpecs = serviceSpecProcessor.process(profileArg, serviceSpecsFiles);
        } catch (HyscaleException e) {
            if (WorkflowLogger.isDisabled()) {
                StructuredOutputHandler.prepareOutput(WorkflowConstants.DEPLOYMENT_ERROR, e.getMessage());
            }
            throw e;
        }

        // Construct WorkflowContext
        List<WorkflowContext> contextList = new ArrayList<>();
        for (EffectiveServiceSpec each : effectiveServiceSpecs) {
            if (each != null && each.getServiceSpec() != null && each.getServiceMetadata() != null) {
                WorkflowContextBuilder builder = new WorkflowContextBuilder(appName);
                try {
                    builder.withProfile(each.getServiceMetadata().getEnvName());
                    builder.withAuthConfig(authConfigBuilder.getAuthConfig());
                    builder.withService(each.getServiceSpec());
                    builder.withNamespace(namespace);
                    contextList.add(builder.get());
                } catch (HyscaleException e) {
                    logger.error("Error while preparing workflow context ", e);
                    if (WorkflowLogger.isDisabled()) {
                        StructuredOutputHandler.prepareOutput(WorkflowConstants.DEPLOYMENT_ERROR, e.getMessage());
                    }
                    throw e;
                }
            }
        }

        postValidators.forEach(each -> inputSpecPostValidator.addValidator(each));

        if (!inputSpecPostValidator.validate(contextList)) {
            WorkflowLogger.logPersistedActivities();
            if(WorkflowLogger.isDisabled()){
                outputHandler.generateErrorMessage(WorkflowConstants.DEPLOYMENT_ERROR);
            }
            return ToolConstants.INVALID_INPUT_ERROR_CODE;
        }

        boolean isCommandFailed = false;
        for (WorkflowContext workflowContext : contextList) {
            String serviceName = workflowContext.getServiceName();
            WorkflowLogger.header(ControllerActivity.SERVICE_NAME, serviceName);

            workflowContext.addAttribute(WorkflowConstants.DEPLOY_START_TIME, System.currentTimeMillis());
            SetupConfig.clearAbsolutePath();
            SetupConfig.setAbsolutePath(serviceVsSpecFile.get(serviceName).getAbsoluteFile().getParent());
            workflowContext.addAttribute(WorkflowConstants.VERBOSE, verbose);

            // clean up service dir before dockerfileGen
            workflowContext.addAttribute(WorkflowConstants.CLEAN_UP_SERVICE_DIR, true);

            executeInvoker(dockerfileGeneratorComponentInvoker, workflowContext);

            executeInvoker(imageBuildComponentInvoker, workflowContext);

            executeInvoker(manifestGeneratorComponentInvoker, workflowContext);

            if (!workflowContext.isFailed()) {
                List<Manifest> manifestList = (List<Manifest>) workflowContext.getAttribute(WorkflowConstants.OUTPUT);
                workflowContext.addAttribute(WorkflowConstants.GENERATED_MANIFESTS, manifestList);
                WorkflowLogger.header(ControllerActivity.STARTING_DEPLOYMENT);
                executeInvoker(deployComponentInvoker, workflowContext);
            }
            logWorkflowInfo(workflowContext);
            isCommandFailed = isCommandFailed ? isCommandFailed : workflowContext.isFailed();
            if (WorkflowLogger.isDisabled() && !isCommandFailed) {
                ServiceStatus serviceStatus = new ServiceStatus();
                serviceStatus.setName(workflowContext.getServiceName());
                if (workflowContext.getAttribute(WorkflowConstants.SERVICE_IP) != null) {
                    serviceStatus.setMessage(workflowContext.getAttribute(WorkflowConstants.SERVICE_IP).toString());
                }
                if (workflowContext.getAttribute(WorkflowConstants.SERVICE_URL) != null) {
                    serviceStatus.setMessage(workflowContext.getAttribute(WorkflowConstants.SERVICE_URL).toString());
                }
                JsonObject json = (JsonObject) jsonParser.parse(GsonProviderUtil.getPrettyGsonBuilder().toJson(serviceStatus));
                jsonArr.add(json);
            }
        }
        if(WorkflowLogger.isDisabled()) {
            StructuredOutputHandler.prepareOutput(WorkflowConstants.SERVICE_STATUS,jsonArr);
        }
        return isCommandFailed ? ToolConstants.HYSCALE_ERROR_CODE : 0;
    }
This class executes 'hyscale deploy service' command
It is a sub-command of the 'hyscale deploy' command

 Options:
 namespace - name of the namespace in which the service to be deployed
 appName - name of the app to logically group your services
 serviceSpecs - list of service specs that are to be deployed
 profiles - list of profiles for services
 profile - profile name to look for. Profile file should be present for all services in service spec (profiles and profile are mutually exclusive)
 verbose - prints the verbose output of the deployment
<p>
Eg 1: hyscale deploy service -f svca.hspec -f svcb.hspec -p dev-svca.hprof -n dev -a sample
Eg 2: hyscale deploy service -f svca.hspec -f svcb.hspec -P dev -n dev -a sample
<p>
Responsible for deploying a service with the given 'hspec' to
the configured kubernetes cluster.
performs a validation of input before starting deployment.
Performs functions ranging from image building to manifest generation to deployment.
Creates a WorkflowContext to communicate across all deployment stages.
@see HyscaleDeployCommand
Every command/sub-command has to implement the {@link Callable} so that
whenever the command is executed the {@link #call()}
method will be invoked
workflow-controller/controller-service/src/main/java/io/hyscale/controller/commands/deploy/HyscaleDeployServiceCommand.java