/* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * Copyright (c) 2013, MPL CodeInside http://codeinside.ru */ package ru.codeinside.gws3970c; import ru.codeinside.gws.api.Client; import ru.codeinside.gws.api.ClientFailureAware; import ru.codeinside.gws.api.ClientRequest; import ru.codeinside.gws.api.ClientResponse; import ru.codeinside.gws.api.Enclosure; import ru.codeinside.gws.api.ExchangeContext; import ru.codeinside.gws.api.InfoSystem; import ru.codeinside.gws.api.Packet; import ru.codeinside.gws.api.Revision; import ru.codeinside.gws.api.XmlTypes; import ru.codeinside.gws3970c.types.AppData; import ru.codeinside.gws3970c.types.data.DataRow; import ru.codeinside.gws3970c.types.data.Result; import ru.codeinside.gws3970c.types.data.SystemParams; import javax.xml.datatype.DatatypeConfigurationException; import javax.xml.datatype.DatatypeFactory; import javax.xml.namespace.QName; import javax.xml.soap.Name; import javax.xml.soap.SOAPFault; import javax.xml.ws.WebServiceException; import javax.xml.ws.soap.SOAPFaultException; import java.net.URL; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.GregorianCalendar; import java.util.LinkedHashSet; import java.util.List; import java.util.Set; import java.util.UUID; final public class UniversalClient implements Client, ClientFailureAware { public static final QName UPDATE_STATUS = new QName("http://mvv.oep.com/", "updateStatus"); public static final QName PUT_DATA = new QName("http://mvv.oep.com/", "putData"); public static final String SMEV_REQUEST_ID = "smevRequestId"; public static final String SMEV_ORIGIN_REQUEST_ID = "smevOriginRequestId"; public static final String APP_ID = "app_id"; public static final String SMEV_POOL = "smevPool"; public static final String SMEV_REJECT = "smevReject"; @Override public Revision getRevision() { return Revision.rev120315; } @Override public URL getWsdlUrl() { return getClass().getClassLoader().getResource("gws3970/mvvact.wsdl"); } @Override public ClientRequest createClientRequest(ExchangeContext ctx) { final Packet packet = new Packet(); packet.originRequestIdRef = (String) ctx.getVariable(SMEV_ORIGIN_REQUEST_ID); packet.requestIdRef = (String) ctx.getVariable(SMEV_REQUEST_ID); boolean pooling = packet.originRequestIdRef != null || packet.requestIdRef != null; packet.recipient = new InfoSystem("PNZR01581", "Комплексная система предоставления государственных и муниципальных услуг Пензенской области"); packet.typeCode = Packet.Type.SERVICE; packet.date = new Date(); packet.serviceName = "PENZUniversalMVV"; packet.exchangeType = "1"; // 1 - Запрос на оказание услуги packet.testMsg = (String) ctx.getVariable("smevTest"); packet.status = pooling ? Packet.Status.PING : Packet.Status.REQUEST; final ClientRequest request = new ClientRequest(); request.signRequired = true; request.packet = packet; request.appData = createAppData(ctx, pooling); request.action = pooling ? UPDATE_STATUS : PUT_DATA; if (!pooling) { final List<Enclosure> enclosures = new ArrayList<Enclosure>(); for (String name : ctx.getVariableNames()) { if (name.startsWith("appData_")) { if (ctx.isEnclosure(name)) { final Enclosure enclosure = ctx.getEnclosure(name); enclosure.code = name; enclosures.add(enclosure); } } } final Object requestCode = ctx.getVariable("smevRequestCode"); request.enclosureDescriptor = requestCode != null ? requestCode.toString() : "metadata"; request.enclosures = enclosures.toArray(new Enclosure[enclosures.size()]); } return request; } private String createAppData(ExchangeContext ctx, boolean pooled) { final Result result = new Result(); SystemParams params = new SystemParams(); Long appId = (Long) ctx.getVariable(APP_ID); if (appId != null) { params.setAppId(appId); } GregorianCalendar c = new GregorianCalendar(); try { params.setStatusDate(DatatypeFactory.newInstance().newXMLGregorianCalendar(c)); } catch (DatatypeConfigurationException e) { } result.setParams(params); List<DataRow> dataRowList = new ArrayList<DataRow>(); result.setDataRow(dataRowList); Set<String> variableNames = new LinkedHashSet<String>(); for (String name : ctx.getVariableNames()) { if (name.startsWith("appData_") || name.startsWith("+appData_")) { variableNames.add(name); } } variableNames.add("flowName"); variableNames.add("procedureCode"); if (pooled) { variableNames.add("internalRequestId"); } for (String variable : variableNames) { if (!ctx.isEnclosure(variable) && ctx.getVariable(variable) != null) { DataRow dataRow = new DataRow(); dataRow.setName(variable); if (ctx.getVariable(variable) instanceof Date) { String formattedDate = new SimpleDateFormat("dd/MM/yyyy").format(ctx.getVariable(variable)); dataRow.setValue(formattedDate); } else { dataRow.setValue(ctx.getVariable(variable).toString()); } dataRowList.add(dataRow); } } return new XmlTypes(Result.class).toXml(result); } @Override public void processClientResponse(ClientResponse response, ExchangeContext context) { if (response.verifyResult.error != null) { context.setVariable(SMEV_POOL, false); context.setVariable(SMEV_REJECT, true); context.setVariable("status_code", "ЭЦП:" + response.verifyResult.error); return; } boolean pooled = context.getVariable(SMEV_ORIGIN_REQUEST_ID) != null || context.getVariable(SMEV_REQUEST_ID) != null; if (!pooled) { boolean isAccepted = response.packet.status == Packet.Status.ACCEPT; context.setVariable(SMEV_POOL, isAccepted); if (isAccepted) { updateRequestChain(response, context, true); } context.setVariable(SMEV_REJECT, !isAccepted); } else { boolean isProcess = response.packet.status == Packet.Status.PROCESS; context.setVariable(SMEV_POOL, isProcess); if (isProcess) { updateRequestChain(response, context, false); } else { context.setVariable(SMEV_REJECT, response.packet.status == Packet.Status.REJECT); } } final AppData appData = XmlTypes.elementToBean(response.appData, AppData.class); for (final Result result : appData.getResult()) { for (final DataRow row : result.getDataRow()) { context.setVariable(row.getName(), row.getValue()); } final SystemParams systemParams = result.getParams(); context.setVariable(APP_ID, systemParams.getAppId()); context.setVariable("form_id", systemParams.getFormId()); context.setVariable("org_id", systemParams.getOrgId()); context.setVariable("status_code", systemParams.getStatusCode()); context.setVariable("status_pgu", systemParams.getStatusPgu()); context.setVariable("status_title", systemParams.getStatusTitle()); context.setVariable("status_date", systemParams.getStatusDate()); } if (response.enclosures != null) { for (final Enclosure enclosure : response.enclosures) { String name = enclosure.code; if (name == null) { name = "enclosure_" + enclosure.zipPath.replace('/', '_'); } context.addEnclosure(name, enclosure); } } } private void updateRequestChain(ClientResponse response, ExchangeContext context, boolean start) { if (start) { context.setVariable(SMEV_ORIGIN_REQUEST_ID, response.packet.originRequestIdRef); } if (response.routerPacket != null) { context.setVariable(SMEV_REQUEST_ID, response.routerPacket.messageId); } else { context.setVariable(SMEV_REQUEST_ID, UUID.randomUUID().toString()); } } @Override public void processFailure(ExchangeContext ctx, RuntimeException failure) { if (failure instanceof SOAPFaultException) { ctx.setVariable(SMEV_POOL, false); ctx.setVariable(SMEV_REJECT, true); ctx.setVariable("status_code", createSoapFaultMessage((SOAPFaultException) failure)); return; } if (failure instanceof WebServiceException) { ctx.setVariable(SMEV_POOL, false); ctx.setVariable(SMEV_REJECT, true); ctx.setVariable("status_code", "Ошибка связи с поставщиком: " + failure.getMessage()); return; } throw failure; } private String createSoapFaultMessage(SOAPFaultException failure) { SOAPFault fault = failure.getFault(); StringBuilder message = new StringBuilder("Ошибка поставщика"); Name code = fault.getFaultCodeAsName(); if (code != null) { message.append(" (").append(code.getLocalName()).append(')'); } message.append(": "); message.append(fault.getFaultString()); return message.toString(); } }