diff options
author | Smokowski, Steven <steve.smokowski@att.com> | 2019-05-15 14:19:49 -0400 |
---|---|---|
committer | Benjamin, Max (mb388a) <mb388a@us.att.com> | 2019-05-15 14:19:58 -0400 |
commit | e4687eeb77d9fddf14935894026aec0b1c9e3ac9 (patch) | |
tree | 47c85cd95c71d36a404da6c83fbbb5d11fb0fb2c /adapters/mso-openstack-adapters/src/main/java | |
parent | f9c309fb9e789225ccd6b02ec9ab4777bbd4021c (diff) |
store openstack request status in requestdb
Openstack request status now stored in request db
Change-Id: Ida8f4f613d406c2b834ab190e01d5aaf2f16dd3d
Issue-ID: SO-1867
Signed-off-by: Benjamin, Max (mb388a) <mb388a@us.att.com>
Diffstat (limited to 'adapters/mso-openstack-adapters/src/main/java')
6 files changed, 150 insertions, 45 deletions
diff --git a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/audit/AbstractAuditService.java b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/audit/AbstractAuditService.java index 2e62beb083..5060e554eb 100644 --- a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/audit/AbstractAuditService.java +++ b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/audit/AbstractAuditService.java @@ -1,3 +1,24 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP - SO + * ================================================================================ + * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + + package org.onap.so.adapters.audit; import java.util.Optional; diff --git a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/network/NetworkAdapterRest.java b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/network/NetworkAdapterRest.java index b12d2397f9..df2c3a2973 100644 --- a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/network/NetworkAdapterRest.java +++ b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/network/NetworkAdapterRest.java @@ -24,11 +24,6 @@ package org.onap.so.adapters.network; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; -import io.swagger.annotations.ApiResponse; -import io.swagger.annotations.ApiResponses; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -47,6 +42,7 @@ import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import javax.xml.ws.Holder; import org.apache.http.HttpStatus; +import org.onap.logging.ref.slf4j.ONAPLogConstants; import org.onap.so.adapters.network.exceptions.NetworkException; import org.onap.so.adapters.nwrest.ContrailNetwork; import org.onap.so.adapters.nwrest.CreateNetworkError; @@ -74,9 +70,15 @@ import org.onap.so.openstack.beans.RouteTarget; import org.onap.so.openstack.exceptions.MsoExceptionCategory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.slf4j.MDC; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.transaction.annotation.Transactional; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import io.swagger.annotations.ApiResponse; +import io.swagger.annotations.ApiResponses; @Path("/v1/networks") @Api(value = "/v1/networks", description = "root of network adapters restful web service") @@ -160,6 +162,11 @@ public class NetworkAdapterRest { @Override public void run() { + try { + MDC.put(ONAPLogConstants.MDCs.REQUEST_ID, req.getMsoRequest().getRequestId()); + } catch (Exception e) { + logger.error("Error adding RequestId to MDC", e); + } logger.debug("CreateNetworkTask start"); try { // Synchronous Web Service Outputs @@ -317,6 +324,11 @@ public class NetworkAdapterRest { @Override public void run() { + try { + MDC.put(ONAPLogConstants.MDCs.REQUEST_ID, req.getMsoRequest().getRequestId()); + } catch (Exception e) { + logger.error("Error adding RequestId to MDC", e); + } logger.debug("DeleteNetworkTask start"); try { Holder<Boolean> networkDeleted = new Holder<>(); @@ -462,6 +474,11 @@ public class NetworkAdapterRest { @Override public void run() { + try { + MDC.put(ONAPLogConstants.MDCs.REQUEST_ID, req.getNetworkRollback().getMsoRequest().getRequestId()); + } catch (Exception e) { + logger.error("Error adding RequestId to MDC", e); + } logger.debug("RollbackNetworkTask start"); try { NetworkRollback nwr = req.getNetworkRollback(); @@ -550,6 +567,11 @@ public class NetworkAdapterRest { @Override public void run() { + try { + MDC.put(ONAPLogConstants.MDCs.REQUEST_ID, req.getMsoRequest().getRequestId()); + } catch (Exception e) { + logger.error("Error adding RequestId to MDC", e); + } logger.debug("UpdateNetworkTask start"); try { Holder<Map<String, String>> subnetIdMap = new Holder<>(); diff --git a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/vnf/VnfAdapterRest.java b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/vnf/VnfAdapterRest.java index 20ce4170af..686410f14c 100644 --- a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/vnf/VnfAdapterRest.java +++ b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/vnf/VnfAdapterRest.java @@ -41,6 +41,7 @@ import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import javax.xml.ws.Holder; import org.apache.http.HttpStatus; +import org.onap.logging.ref.slf4j.ONAPLogConstants; import org.onap.so.adapters.vnf.exceptions.VnfException; import org.onap.so.adapters.vnfrest.CreateVfModuleRequest; import org.onap.so.adapters.vnfrest.CreateVfModuleResponse; @@ -61,6 +62,7 @@ import org.onap.so.openstack.beans.VnfStatus; import org.onap.so.openstack.exceptions.MsoExceptionCategory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.slf4j.MDC; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.transaction.annotation.Transactional; @@ -86,19 +88,10 @@ public class VnfAdapterRest { @Autowired private MsoVnfAdapterImpl vnfAdapter; - // TODO Logging, SkipAAI, CREATED flags, Integrate with BPEL, Auth, @Autowired private Provider<BpelRestClient> bpelRestClientProvider; - - /* - * URL:http://localhost:8080/vnfs/rest/v1/vnfs/<aaivnfid>/vf-modules/<aaimodid> REQUEST: {"deleteVfModuleRequest": - * {"cloudSiteId": "DAN", "tenantId": "214b428a1f554c02935e66330f6a5409", "vnfId": "somevnfid", "vfModuleId": - * "somemodid", "vfModuleStackId": "4e567676-e266-4594-a3a6-131c8a2baf73", "messageId": "ra.1", "notificationUrl": - * "http://localhost:8089/vnfmock", "skipAAI": true, "msoRequest": { "requestId": "ra1", "serviceInstanceId": "sa1" - * }} } - */ @DELETE @Path("{aaiVnfId}/vf-modules/{aaiVfModuleId}") @Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON}) @@ -176,11 +169,14 @@ public class VnfAdapterRest { @Override public void run() { try { + try { + MDC.put(ONAPLogConstants.MDCs.REQUEST_ID, req.getMsoRequest().getRequestId()); + } catch (Exception e) { + logger.error("Error adding RequestId to MDC", e); + } String cloudsite = req.getCloudSiteId(); Holder<Map<String, String>> outputs = new Holder<>(); if (cloudsite != null && !cloudsite.equals(TESTING_KEYWORD)) { - // vnfAdapter.deleteVnf (req.getCloudSiteId(), req.getTenantId(), req.getVfModuleStackId(), - // req.getMsoRequest()); vnfAdapter.deleteVfModule(req.getCloudSiteId(), req.getCloudOwner(), req.getTenantId(), req.getVfModuleStackId(), req.getMsoRequest(), outputs); } @@ -200,13 +196,7 @@ public class VnfAdapterRest { } } - /* - * URL:http://localhost:8080/vnfs/rest/v1/vnfs/<aaiVnfId>/vf-modules/<aaiVfModuleId>?cloudSiteId=DAN&tenantId= - * vfModule?&skipAAI=TRUE&msoRequest.requestId=ra1&msoRequest.serviceInstanceId=si1&vfModuleName=T2N2S1 RESP: - * {"queryVfModuleResponse": { "vfModuleId": "AvfmodId", "vfModuleOutputs": {"entry": { "key": - * "server_private_ip_1", "value": "10.100.1.25" }}, "vfModuleStackId": - * "RaaVnf1/abfa8a6d-feb1-40af-aea3-109403b1cf6b", "vnfId": "AvnfID", "vnfStatus": "ACTIVE" }} - */ + @GET @Path("{aaiVnfId}/vf-modules/{aaiVfModuleId}") @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON}) @@ -340,6 +330,11 @@ public class VnfAdapterRest { public void run() { logger.debug("CreateVfModuleTask start"); try { + try { + MDC.put(ONAPLogConstants.MDCs.REQUEST_ID, req.getMsoRequest().getRequestId()); + } catch (Exception e) { + logger.error("Error adding RequestId to MDC", e); + } // Synchronous Web Service Outputs Holder<String> vfModuleStackId = new Holder<>(); Holder<Map<String, String>> outputs = new Holder<>(); @@ -449,9 +444,11 @@ public class VnfAdapterRest { @Override public void run() { try { - // MsoVnfAdapter vnfAdapter = new MsoVnfAdapterImpl (msoPropertiesFactory, cloudConfigFactory); - - // Synchronous Web Service Outputs + try { + MDC.put(ONAPLogConstants.MDCs.REQUEST_ID, req.getMsoRequest().getRequestId()); + } catch (Exception e) { + logger.error("Error adding RequestId to MDC", e); + } Holder<String> vfModuleStackId = new Holder<>(); Holder<Map<String, String>> outputs = new Holder<>(); Holder<VnfRollback> vnfRollback = new Holder<>(); @@ -481,13 +478,7 @@ public class VnfAdapterRest { } } - /* - * URL:http://localhost:8080/vnfs/rest/v1/vnfs/<aaivnfid>/vf-modules/<aaimodid>/rollback REQUEST: - * {"deleteVfModuleRequest": {"cloudSiteId": "DAN", "tenantId": "214b428a1f554c02935e66330f6a5409", "vnfId": - * "somevnfid", "vfModuleId": "somemodid", "vfModuleStackId": "4e567676-e266-4594-a3a6-131c8a2baf73", "messageId": - * "ra.1", "notificationUrl": "http://localhost:8089/vnfmock", "skipAAI": true, "msoRequest": { "requestId": "ra1", - * "serviceInstanceId": "sa1" }} } - */ + @DELETE @Path("{aaiVnfId}/vf-modules/{aaiVfModuleId}/rollback") @Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON}) @@ -557,6 +548,11 @@ public class VnfAdapterRest { @Override public void run() { try { + try { + MDC.put(ONAPLogConstants.MDCs.REQUEST_ID, req.getVfModuleRollback().getMsoRequest().getRequestId()); + } catch (Exception e) { + logger.error("Error adding RequestId to MDC", e); + } VfModuleRollback vmr = req.getVfModuleRollback(); VnfRollback vrb = new VnfRollback(vmr.getVfModuleStackId(), vmr.getTenantId(), vmr.getCloudOwner(), vmr.getCloudSiteId(), true, true, vmr.getMsoRequest(), null, null, null, null); diff --git a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/vnf/VnfAdapterRestV2.java b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/vnf/VnfAdapterRestV2.java index 7c6d251263..5b831047ad 100644 --- a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/vnf/VnfAdapterRestV2.java +++ b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/vnf/VnfAdapterRestV2.java @@ -40,6 +40,7 @@ import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import javax.xml.ws.Holder; import org.apache.http.HttpStatus; +import org.onap.logging.ref.slf4j.ONAPLogConstants; import org.onap.so.adapters.vnf.exceptions.VnfException; import org.onap.so.adapters.vnfrest.CreateVfModuleRequest; import org.onap.so.adapters.vnfrest.CreateVfModuleResponse; @@ -60,6 +61,7 @@ import org.onap.so.openstack.beans.VnfStatus; import org.onap.so.openstack.exceptions.MsoExceptionCategory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.slf4j.MDC; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import io.swagger.annotations.Api; @@ -132,6 +134,7 @@ public class VnfAdapterRestV2 { // This is an asynchronous request try { Thread t1 = new Thread(task); + MDC.getCopyOfContextMap(); t1.start(); } catch (Exception e) { // problem handling delete, send generic failure as sync resp to caller @@ -178,6 +181,11 @@ public class VnfAdapterRestV2 { @Override public void run() { try { + try { + MDC.put(ONAPLogConstants.MDCs.REQUEST_ID, req.getMsoRequest().getRequestId()); + } catch (Exception e) { + logger.error("Error adding RequestId to MDC", e); + } String cloudsite = req.getCloudSiteId(); Holder<Map<String, String>> outputs = new Holder<>(); if (cloudsite != null && !cloudsite.equals(TESTING_KEYWORD)) { @@ -201,6 +209,7 @@ public class VnfAdapterRestV2 { bpelClient.bpelPost(getResponse(), req.getNotificationUrl(), sendxml); } logger.debug("Delete vfModule exit: code=" + getStatusCode() + RESP + getResponse()); + MDC.clear(); } } @@ -353,6 +362,11 @@ public class VnfAdapterRestV2 { public void run() { logger.debug("CreateVfModuleTask start"); try { + try { + MDC.put(ONAPLogConstants.MDCs.REQUEST_ID, req.getMsoRequest().getRequestId()); + } catch (Exception e) { + logger.error("Error adding RequestId to MDC", e); + } // Synchronous Web Service Outputs Holder<String> vfModuleStackId = new Holder<>(); Holder<Map<String, String>> outputs = new Holder<>(); @@ -467,8 +481,11 @@ public class VnfAdapterRestV2 { @Override public void run() { try { - // MsoVnfAdapter vnfAdapter = new MsoVnfAdapterImpl (msoPropertiesFactory, cloudConfigFactory); - + try { + MDC.put(ONAPLogConstants.MDCs.REQUEST_ID, req.getMsoRequest().getRequestId()); + } catch (Exception e) { + logger.error("Error adding RequestId to MDC", e); + } // Synchronous Web Service Outputs Holder<String> vfModuleStackId = new Holder<>(); Holder<Map<String, String>> outputs = new Holder<>(); @@ -577,6 +594,11 @@ public class VnfAdapterRestV2 { @Override public void run() { try { + try { + MDC.put(ONAPLogConstants.MDCs.REQUEST_ID, req.getVfModuleRollback().getMsoRequest().getRequestId()); + } catch (Exception e) { + logger.error("Error adding RequestId to MDC", e); + } VfModuleRollback vmr = req.getVfModuleRollback(); VnfRollback vrb = new VnfRollback(vmr.getVfModuleStackId(), vmr.getTenantId(), vmr.getCloudOwner(), vmr.getCloudSiteId(), true, vmr.isVfModuleCreated(), vmr.getMsoRequest(), null, null, null, diff --git a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/vnf/VolumeAdapterRest.java b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/vnf/VolumeAdapterRest.java index c02a872a85..87df7fdc37 100644 --- a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/vnf/VolumeAdapterRest.java +++ b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/vnf/VolumeAdapterRest.java @@ -25,11 +25,6 @@ package org.onap.so.adapters.vnf; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; -import io.swagger.annotations.ApiResponse; -import io.swagger.annotations.ApiResponses; import java.util.HashMap; import java.util.Map; import javax.inject.Provider; @@ -47,6 +42,7 @@ import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import javax.xml.ws.Holder; import org.apache.http.HttpStatus; +import org.onap.logging.ref.slf4j.ONAPLogConstants; import org.onap.so.adapters.vnf.exceptions.VnfException; import org.onap.so.adapters.vnfrest.CreateVolumeGroupRequest; import org.onap.so.adapters.vnfrest.CreateVolumeGroupResponse; @@ -67,8 +63,14 @@ import org.onap.so.openstack.beans.VnfStatus; import org.onap.so.openstack.exceptions.MsoExceptionCategory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.slf4j.MDC; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import io.swagger.annotations.ApiResponse; +import io.swagger.annotations.ApiResponses; /** * This class services calls to the REST interface for VNF Volumes (http://host:port/vnfs/rest/v1/volume-groups) Both @@ -155,6 +157,11 @@ public class VolumeAdapterRest { @Override public void run() { + try { + MDC.put(ONAPLogConstants.MDCs.REQUEST_ID, req.getMsoRequest().getRequestId()); + } catch (Exception e) { + logger.error("Error adding RequestId to MDC", e); + } logger.debug("CreateVFModule VolumesTask start"); try { // Synchronous Web Service Outputs @@ -302,6 +309,11 @@ public class VolumeAdapterRest { @Override public void run() { + try { + MDC.put(ONAPLogConstants.MDCs.REQUEST_ID, req.getMsoRequest().getRequestId()); + } catch (Exception e) { + logger.error("Error adding RequestId to MDC", e); + } logger.debug("DeleteVNFVolumesTask start"); try { if (!req.getCloudSiteId().equals(TESTING_KEYWORD)) { @@ -394,6 +406,11 @@ public class VolumeAdapterRest { @Override public void run() { + try { + MDC.put(ONAPLogConstants.MDCs.REQUEST_ID, req.getVolumeGroupRollback().getMsoRequest().getRequestId()); + } catch (Exception e) { + logger.error("Error adding RequestId to MDC", e); + } logger.debug("DeleteVNFVolumesTask start"); try { VolumeGroupRollback vgr = req.getVolumeGroupRollback(); @@ -487,6 +504,11 @@ public class VolumeAdapterRest { public void run() { logger.debug("UpdateVNFVolumesTask start"); try { + try { + MDC.put(ONAPLogConstants.MDCs.REQUEST_ID, req.getMsoRequest().getRequestId()); + } catch (Exception e) { + logger.error("Error adding RequestId to MDC", e); + } Holder<Map<String, String>> outputs = new Holder<>(); Holder<VnfRollback> vnfRollback = new Holder<>(); String completeVnfVfModuleType = req.getVnfType() + "::" + req.getVfModuleType(); diff --git a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/vnf/VolumeAdapterRestV2.java b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/vnf/VolumeAdapterRestV2.java index 0ceba20051..77c9b1e2f5 100644 --- a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/vnf/VolumeAdapterRestV2.java +++ b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/vnf/VolumeAdapterRestV2.java @@ -24,11 +24,6 @@ package org.onap.so.adapters.vnf; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; -import io.swagger.annotations.ApiResponse; -import io.swagger.annotations.ApiResponses; import java.util.HashMap; import java.util.Map; import javax.inject.Provider; @@ -46,6 +41,7 @@ import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import javax.xml.ws.Holder; import org.apache.http.HttpStatus; +import org.onap.logging.ref.slf4j.ONAPLogConstants; import org.onap.so.adapters.vnf.exceptions.VnfException; import org.onap.so.adapters.vnfrest.CreateVolumeGroupRequest; import org.onap.so.adapters.vnfrest.CreateVolumeGroupResponse; @@ -66,8 +62,14 @@ import org.onap.so.openstack.beans.VnfStatus; import org.onap.so.openstack.exceptions.MsoExceptionCategory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.slf4j.MDC; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import io.swagger.annotations.ApiResponse; +import io.swagger.annotations.ApiResponses; /** * This class services calls to the REST interface for VNF Volumes (http://host:port/vnfs/rest/v1/volume-groups) Both @@ -158,6 +160,11 @@ public class VolumeAdapterRestV2 { @Override public void run() { + try { + MDC.put(ONAPLogConstants.MDCs.REQUEST_ID, req.getMsoRequest().getRequestId()); + } catch (Exception e) { + logger.error("Error adding RequestId to MDC", e); + } logger.debug("CreateVFModule VolumesTask start"); try { // Synchronous Web Service Outputs @@ -288,6 +295,11 @@ public class VolumeAdapterRestV2 { @Override public void run() { + try { + MDC.put(ONAPLogConstants.MDCs.REQUEST_ID, req.getMsoRequest().getRequestId()); + } catch (Exception e) { + logger.error("Error adding RequestId to MDC", e); + } logger.debug("DeleteVNFVolumesTask start"); String cloudSiteId = req.getCloudSiteId(); try { @@ -383,6 +395,11 @@ public class VolumeAdapterRestV2 { @Override public void run() { + try { + MDC.put(ONAPLogConstants.MDCs.REQUEST_ID, req.getVolumeGroupRollback().getMsoRequest().getRequestId()); + } catch (Exception e) { + logger.error("Error adding RequestId to MDC", e); + } logger.debug("RollbackVNFVolumesTask start"); try { VolumeGroupRollback vgr = req.getVolumeGroupRollback(); @@ -480,6 +497,11 @@ public class VolumeAdapterRestV2 { @Override public void run() { + try { + MDC.put(ONAPLogConstants.MDCs.REQUEST_ID, req.getMsoRequest().getRequestId()); + } catch (Exception e) { + logger.error("Error adding RequestId to MDC", e); + } logger.debug("UpdateVNFVolumesTask start"); try { Holder<Map<String, String>> outputs = new Holder<>(); |