package ru.codeinside.gses.webui.form; import com.sun.org.apache.xerces.internal.parsers.DOMParser; import org.activiti.engine.ProcessEngine; import org.activiti.engine.delegate.BpmnError; import org.activiti.engine.impl.ServiceImpl; import org.activiti.engine.impl.interceptor.Command; import org.activiti.engine.impl.interceptor.CommandContext; import org.activiti.engine.impl.interceptor.CommandExecutor; import org.apache.commons.lang.StringUtils; import org.osgi.framework.InvalidSyntaxException; import org.osgi.framework.ServiceReference; import org.w3c.dom.Element; import org.w3c.dom.NodeList; import org.xml.sax.InputSource; import org.xml.sax.SAXException; import ru.codeinside.adm.AdminService; import ru.codeinside.adm.AdminServiceProvider; import ru.codeinside.adm.database.Bid; import ru.codeinside.adm.database.ExternalGlue; import ru.codeinside.adm.database.InfoSystemService; import ru.codeinside.adm.database.ServiceResponseEntity; import ru.codeinside.gses.activiti.Activiti; import ru.codeinside.gses.service.F3; import ru.codeinside.gses.webui.osgi.Activator; import ru.codeinside.gws.api.Client; import ru.codeinside.gws.api.ClientProtocol; import ru.codeinside.gws.api.ClientRequest; import ru.codeinside.gws.api.Enclosure; import ru.codeinside.gws.api.ExchangeContext; import ru.codeinside.gws.api.InfoSystem; import ru.codeinside.gws.api.ProtocolFactory; import ru.codeinside.gws.api.Server; import ru.codeinside.gws.api.ServerProtocol; import ru.codeinside.gws.api.ServerResponse; import ru.codeinside.gws.api.ServiceDefinition; import ru.codeinside.gws.api.ServiceDefinitionParser; import javax.xml.namespace.QName; import javax.xml.soap.SOAPException; import javax.xml.soap.SOAPMessage; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Map; public class ProtocolUtils { private ProtocolUtils() { throw new UnsupportedOperationException("Static methods only"); } public static final String SMEV_REQUEST_ID = "smevRequestId"; public static final String SMEV_ORIGIN_REQUEST_ID = "smevOriginRequestId"; public static ClientProtocol getClientProtocol(Client client) { if (client == null) { throw new IllegalStateException("Клиент недоступен"); } ClientProtocol clientProtocol; ServiceReference serviceReference = Activator.getContext().getServiceReference(ProtocolFactory.class.getName()); if (serviceReference == null) { throw new IllegalStateException("Сервис недоступен"); } try { ProtocolFactory protocolFactory = (ProtocolFactory) Activator.getContext().getService(serviceReference); clientProtocol = protocolFactory.createClientProtocol(client.getRevision()); } finally { Activator.getContext().ungetService(serviceReference); } return clientProtocol; } public static ServerProtocol getServerProtocol(Server service) { if (service == null) { throw new IllegalStateException("Сервис поставщика недоступен"); } ServerProtocol serverProtocol; ServiceReference serviceReference = Activator.getContext().getServiceReference(ProtocolFactory.class.getName()); if (serviceReference == null) { throw new IllegalStateException("Сервис недоступен"); } try { ProtocolFactory protocolFactory = (ProtocolFactory) Activator.getContext().getService(serviceReference); final ServiceDefinitionParser serviceDefinitionParser = AdminServiceProvider.get().getServiceDefinitionParser(); ServiceDefinition serviceDefinition = serviceDefinitionParser.parseServiceDefinition(service.getWsdlUrl()); serverProtocol = protocolFactory.createServerProtocol(serviceDefinition); } finally { Activator.getContext().ungetService(serviceReference); } return serverProtocol; } public static <T> ServiceReference getServiceReference(String serviceName, Class<T> clazz) { ServiceReference[] references; String filter = "(&(component.name=" + serviceName + "))"; try { references = Activator.getContext().getAllServiceReferences(clazz.getName(), filter); } catch (InvalidSyntaxException e) { throw new IllegalStateException("Не удаётся получить ссылку на сервис " + serviceName); } ServiceReference reference = null; if (references == null || references.length < 1) { throw new IllegalStateException("Сервис " + serviceName + " не найден"); } else if (references.length == 1) { reference = references[0]; } else if (references.length > 1) { // Если есть несколько сервисов с таким именем, берём тот, у которого выше версия for (ServiceReference comparedReference : references) { if (reference == null) { reference = comparedReference; } int comparedReferenceId = Integer.valueOf(comparedReference.getProperty("service.id").toString()); int referenceId = Integer.valueOf(reference.getProperty("service.id").toString()); if (comparedReferenceId > referenceId) { reference = comparedReference; } } } return reference; } public static String getServerName(String taskId) { Bid bid; if (taskId != null) { bid = AdminServiceProvider.get().getBidByTask(taskId); } else { throw new IllegalStateException("Task id is null"); } ExternalGlue glue = bid.getGlue(); if (glue == null) { throw new BpmnError("Нет связи с внешней услугой"); } return glue.getName(); } public static <T> T getService(ServiceReference reference, Class<T> clazz) { return (T) Activator.getContext().getService(reference); } //В возвращаемом списке первый элемент - QName, второй - ServiceDefinition.Port public static List<Object> getQNameAndServicePort(Server server) { final ServiceDefinitionParser serviceDefinitionParser = AdminServiceProvider.get().getServiceDefinitionParser(); ServiceDefinition serviceDefinition = serviceDefinitionParser.parseServiceDefinition(server.getWsdlUrl()); List<Object> result = new ArrayList<Object>(); ServiceDefinition.Service service = null; if (serviceDefinition != null && serviceDefinition.services != null && serviceDefinition.services.keySet().size() == 1) { for (QName name : serviceDefinition.services.keySet()) { result.add(name); service = serviceDefinition.services.get(name); } if (service != null && service.ports.size() == 1) { for (ServiceDefinition.Port port : service.ports.values()) { result.add(port); } } else { throw new IllegalStateException("Порт сервиса поставщика не найден"); } } else { throw new IllegalStateException("Сервис поставщика не найден"); } return result; } public static Enclosure createEnclosureInStartEventContext(TmpAttachment attachment, String variableName) { if (attachment != null) { byte[] content = attachment.getContent(); if (content != null) { String name = StringUtils.trimToNull(attachment.getName()); if (name == null) { name = StringUtils.trimToNull(variableName); } Enclosure enclosure = new Enclosure(name, name, content); enclosure.id = attachment.getId(); enclosure.number = attachment.getId(); enclosure.mimeType = attachment.getType(); enclosure.digest = Activiti.createDigest(content); // enclosure.signature = createSignature(executionId, variableName, content);//TODO enclosure.code = variableName; return enclosure; } } return null; } public static void fillRequestPacket(ClientRequest request, String serviceName) { InfoSystemService currentService = validateAndGetService(serviceName); String address = StringUtils.trimToNull(currentService.getAddress()); if (address != null) { request.portAddress = address; } fillServiceRequestPacket(request, currentService); } public static void fillServiceRequestPacket(ClientRequest request, InfoSystemService currentService) { final ru.codeinside.adm.database.InfoSystem infoSystem = currentService.getInfoSystem(); final ru.codeinside.adm.database.InfoSystem source = currentService.getSource(); if (request.packet.recipient == null) { request.packet.recipient = new InfoSystem(infoSystem.getCode(), infoSystem.getName()); } if (request.packet.sender == null) { request.packet.sender = source == null ? getDefaultSender() : new InfoSystem(source.getCode(), source.getName()); if (request.packet.originator == null) { request.packet.originator = request.packet.sender; } } if (request.packet.date == null) { request.packet.date = new Date(); } } public static void fillClientRequestFromSoapMessage(ClientRequest clientRequest) { String soapMessage = new String(clientRequest.requestMessage); DOMParser parser = new DOMParser(); try { parser.parse(new InputSource(new java.io.StringReader(soapMessage))); Element docElement = parser.getDocument().getDocumentElement(); NodeList senderElement = docElement.getElementsByTagName("smev:Sender"); if (senderElement != null && senderElement.getLength() == 1 && senderElement.item(0).getChildNodes().getLength() == 2) { String code = senderElement.item(0).getChildNodes().item(0).getTextContent(); String name = senderElement.item(0).getChildNodes().item(1).getTextContent(); clientRequest.packet.sender = new InfoSystem(code, name); } NodeList recipientElement = docElement.getElementsByTagName("smev:Recipient"); if (recipientElement != null && recipientElement.getLength() == 1 && recipientElement.item(0).getChildNodes().getLength() == 2) { String code = recipientElement.item(0).getChildNodes().item(0).getTextContent(); String name = recipientElement.item(0).getChildNodes().item(1).getTextContent(); clientRequest.packet.recipient = new InfoSystem(code, name); } NodeList originatorElement = docElement.getElementsByTagName("smev:Originator"); if (originatorElement != null && originatorElement.getLength() == 1 && originatorElement.item(0).getChildNodes().getLength() == 2) { String code = originatorElement.item(0).getChildNodes().item(0).getTextContent(); String name = originatorElement.item(0).getChildNodes().item(1).getTextContent(); clientRequest.packet.originator = new InfoSystem(code, name); } } catch (SAXException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } public static void writeInfoSystemsToContext(String serviceName, ExchangeContext context) { InfoSystemService service = validateAndGetService(serviceName); writeInfoSystemsToContext(service, context); } public static void writeInfoSystemsToContext(InfoSystemService service, ExchangeContext context) { ru.codeinside.adm.database.InfoSystem infoSystem = service.getInfoSystem(); ru.codeinside.adm.database.InfoSystem source = service.getSource(); if (infoSystem != null) { context.setVariable("recipient", new InfoSystem(infoSystem.getCode(), infoSystem.getName())); } if (source != null) { context.setVariable("sender", new InfoSystem(source.getCode(), source.getName())); } } public static InfoSystem getDefaultSender() { ru.codeinside.adm.database.InfoSystem sender = AdminServiceProvider.get().getMainInfoSystem(); if (sender == null) { throw new IllegalStateException("Не задана основная информационная система"); } return new InfoSystem(sender.getCode(), sender.getName()); } public static boolean isPing(ExchangeContext context) { String originRequestIdRef = (String) context.getVariable(SMEV_ORIGIN_REQUEST_ID); String requestIdRef = (String) context.getVariable(SMEV_REQUEST_ID); return originRequestIdRef != null || requestIdRef != null; } private static InfoSystemService validateAndGetService(String serviceName) { List<InfoSystemService> services = AdminServiceProvider.get().getInfoSystemServiceBySName(serviceName); if (services == null || services.isEmpty()) { throw new IllegalStateException("Нет модуля потребителя СМЭВ с именем '" + serviceName + "'"); } return getServiceWithMaxVersion(services); } private static InfoSystemService getServiceWithMaxVersion(List<InfoSystemService> services) { InfoSystemService curService = null; for (InfoSystemService s : services) { if (curService == null) { curService = s; } if (s.getSversion().compareTo(curService.getSversion()) >= 0) { curService = s; } } return curService; } public static byte[] getBytesFromSoapMessage(SOAPMessage message) { ByteArrayOutputStream bos = new ByteArrayOutputStream(); try { message.writeTo(bos); return bos.toByteArray(); } catch (SOAPException e) { e.printStackTrace(); throw new IllegalStateException("Unable serialize SOAPMessage to bytes (IOException): " + e.getMessage()); } catch (IOException e) { e.printStackTrace(); throw new IllegalStateException("Unable serialize SOAPMessage to bytes (IOException): " + e.getMessage()); } } public final static class CreateAndSaveServiceResponseEntity implements F3<Long, ServerResponse, String, Map<Enclosure, String[]>> { /** * @return (Long) serviceResponseEntity.id */ @Override public Long apply(ProcessEngine engine, ServerResponse serverResponse, String taskId, Map<Enclosure, String[]> usedEnclosures) { CommandExecutor commandExecutor = ((ServiceImpl) engine.getFormService()).getCommandExecutor(); return (Long) commandExecutor.execute(new CreateAndSaveServiceResponseEntityCmd(serverResponse, taskId, usedEnclosures)); } } final private static class CreateAndSaveServiceResponseEntityCmd implements Command { private final ServerResponse serverResponse; private final String taskId; private final Map<Enclosure, String[]> usedEnclosures; CreateAndSaveServiceResponseEntityCmd(ServerResponse serverResponse, String taskId, Map<Enclosure, String[]> usedEnclosures) { this.serverResponse = serverResponse; this.taskId = taskId; this.usedEnclosures = usedEnclosures; } @Override public Object execute(CommandContext commandContext) { Bid bid; AdminService adminService = AdminServiceProvider.get(); ServiceResponseEntity responseEntity; if (taskId != null) { bid = adminService.getBidByTask(taskId); if (bid != null) { responseEntity = adminService.getServerResponseEntity(bid.getId(), serverResponse.packet.status.name()); if(responseEntity != null) { return responseEntity.getId(); } else { responseEntity = new ServiceResponseEntity(bid, serverResponse); //TODO писать сюда же SOAPMessage adminService.saveServiceResponse(responseEntity, serverResponse.attachmens, usedEnclosures); return responseEntity.getId(); } } else { throw new IllegalStateException("Bid is null"); } } else { throw new IllegalStateException("Task is null"); } } } }