~ubuntu-branches/ubuntu/raring/ginkgocadx/raring-proposed

« back to all changes in this revision

Viewing changes to src/cadxcore/commands/sendhl7command.cpp

  • Committer: Package Import Robot
  • Author(s): Andreas Tille
  • Date: 2011-09-09 08:39:26 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: package-import@ubuntu.com-20110909083926-iktecd132cnku5cd
Tags: 2.5.4.0~rc-1
New upstream version (patches were applied)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
*
 
3
*  $Id: sendhl7command.cpp 4099 2011-08-29 11:27:03Z tovar $
 
4
*  Ginkgo CADx Project
 
5
*
 
6
*  Copyright 2008-10 MetaEmotion S.L. All rights reserved.
 
7
*  http://ginkgo-cadx.com
 
8
*
 
9
*  This file is licensed under LGPL v3 license.
 
10
*  See License.txt for details
 
11
*
 
12
*/
 
13
//#define _GINKGO_TRACE
 
14
 
 
15
 
 
16
#include <wx/thread.h>
 
17
#include <endpoint/endpoint.h>
 
18
#include "sendhl7command.h"
 
19
#include <main/controllers/controladorlog.h>
 
20
#include <api/imodelohl7.h>
 
21
#include <api/iguiasmensajeriasacyl.h>
 
22
 
 
23
#define IDC_SEND_HL7                                                            117
 
24
 
 
25
// Singleton de persistencia
 
26
namespace GADAPI
 
27
{
 
28
        SendHL7CommandParams::SendHL7CommandParams(const std::list<GIL::HL7::MensajeHL7>& messages)
 
29
        {
 
30
                this->messages = messages;
 
31
                m_idLastSock = -1;
 
32
                m_pSemaphore = new wxSemaphore;
 
33
        }
 
34
 
 
35
        SendHL7CommandParams::~SendHL7CommandParams()
 
36
        {
 
37
                delete m_pSemaphore;
 
38
        }
 
39
 
 
40
        SendHL7Command::SendHL7Command(SendHL7CommandParams* pParams) : IComando(pParams)
 
41
        {
 
42
                m_pSendParams = pParams;
 
43
                
 
44
                SetId(IDC_SEND_HL7);
 
45
                EsperaA(IDC_SEND_HL7);
 
46
        }
 
47
 
 
48
        void SendHL7Command::Execute()
 
49
        {
 
50
                int current = 1;
 
51
                for(std::list<GIL::HL7::MensajeHL7>::iterator it = m_pSendParams->messages.begin(); it!=m_pSendParams->messages.end(); it++) 
 
52
                {
 
53
                        bool sent = false;
 
54
                        while (!sent && !EstaAbortado())
 
55
                        {
 
56
                                float currentProgress = (float)(current-1)/m_pSendParams->messages.size();
 
57
                                {
 
58
                                        wxString strTmp = wxString::Format(_("Sending HL7 message %d of %d"), current, m_pSendParams->messages.size());
 
59
                                        NotificarProgreso(currentProgress, std::string(strTmp.ToUTF8()));
 
60
                                        LOG_DEBUG("Core/HL7", "Comienza el procesamiento del mensaje "<<(*it).m_id)
 
61
                                }
 
62
 
 
63
                                try {
 
64
                                        switch((*it).m_protocolo) {
 
65
                                                case GIL::HL7::IControladorHL7::TP_MLLP:
 
66
                                                        EnviarMensajeMLLP((*it).m_mensaje,(*it).m_destino,(*it).m_procesarACK,(*it).m_msgControlId);
 
67
                                                        GIL::HL7::ControladorBBDDHl7::Instance()->ActualizarEstadoMensaje((*it).m_id,GIL::HL7::MensajeHL7::TE_Enviado,"");
 
68
                                                        LOG_DEBUG("Core/HL7", _Std("Message successfully sent"))
 
69
                                                        sent = true;
 
70
                                                        break;
 
71
                                                default:
 
72
                                                        throw GIL::HL7::HL7Exception(_Std("Unknown protocol"));
 
73
                                        }
 
74
                                } catch(GIL::HL7::HL7Exception& ex) {
 
75
                                        LOG_ERROR("Core/HL7", _Std("Error sending message:") << ex)
 
76
                                        //ha ocurrido un error
 
77
 
 
78
                                        //al primer error se para
 
79
                                        if (ex.IsFatal()) {
 
80
                                                GIL::HL7::ControladorBBDDHl7::Instance()->ActualizarEstadoMensaje((*it).m_id,GIL::HL7::MensajeHL7::TE_Error,ex.GetCause().c_str());
 
81
                                        }
 
82
                                        else {
 
83
                                                GIL::HL7::ControladorBBDDHl7::Instance()->ActualizarEstadoMensaje((*it).m_id,GIL::HL7::MensajeHL7::TE_Warning,ex.GetCause().c_str());
 
84
                                        }
 
85
                                        NotificarProgreso(currentProgress, _Std("Error sending HL7 message see log for more details"));
 
86
                                }
 
87
                                catch(...) {
 
88
                                        LOG_DEBUG("Core/HL7", _Std("Error sending message:") << " " <<_Std("Unknown error"));
 
89
                                        GIL::HL7::ControladorBBDDHl7::Instance()->ActualizarEstadoMensaje((*it).m_id, GIL::HL7::MensajeHL7::TE_Error, _Std("Unknown error"));
 
90
                                }
 
91
                                if (!sent) {
 
92
                                        //wait one minute
 
93
                                        m_pSendParams->m_pSemaphore->WaitTimeout(60000);
 
94
                                }
 
95
                        } //while !sent
 
96
                }
 
97
                
 
98
        }
 
99
 
 
100
        void SendHL7Command::Update()
 
101
        {
 
102
                if (EstaAbortado()) {
 
103
                    return;
 
104
                }
 
105
 
 
106
        }
 
107
 
 
108
        void SendHL7Command::OnAbort()
 
109
        {
 
110
                if (m_pSendParams->m_idLastSock != -1) {
 
111
                        Endpoint::ShutdownSocket(m_pSendParams->m_idLastSock, Endpoint::BOTH);
 
112
                }
 
113
                m_pSendParams->m_pSemaphore->Post();
 
114
        }
 
115
 
 
116
 
 
117
        
 
118
/* Envia el mensaje por MLLP */
 
119
        void SendHL7Command::EnviarMensajeMLLP(const std::string& msg, const std::string& url, bool procesarACK, const std::string& msgControlId)
 
120
        {
 
121
                const std::string START_BLOCK = "\x0b";
 
122
                const std::string END_BLOCK   = "\x1C";
 
123
                const std::string END_MSG     = "\x0D";
 
124
 
 
125
                #ifndef _WIN32
 
126
                signal(SIGPIPE, SIG_IGN);
 
127
                #endif
 
128
                EndpointAddrlist::g_default_family = AF_INET;
 
129
 
 
130
                Endpoint::Initialize();
 
131
 
 
132
                std::cout << "inicializo..." << std::endl;
 
133
                Endpoint ep(TCP | CLIENT, url);
 
134
 
 
135
                if (!ep) {
 
136
                        throw GIL::HL7::HL7Exception(_Std("Failed to start connection") + ep.m_error_str, "COMM");
 
137
                }
 
138
 
 
139
                m_pSendParams->m_idLastSock = ep.m_sockfd;
 
140
 
 
141
                std::stringstream outputStream;
 
142
                outputStream << START_BLOCK << msg << END_BLOCK << END_MSG;
 
143
                long nbytes = ep.Write(outputStream.str());
 
144
                if (nbytes != (long)outputStream.str().size()) {
 
145
                        std::stringstream errmsg;
 
146
                        if (nbytes == -1) {
 
147
                                errmsg << _Std("Error sending message:") << ep.m_error_str;
 
148
                        }
 
149
                        else {
 
150
                                errmsg << _Std("Error sending message. It was sent ") << nbytes << _Std(" bytes from a total of ") << outputStream;
 
151
                        }
 
152
                        throw GIL::HL7::HL7Exception(errmsg.str(), "COMM");
 
153
                }
 
154
 
 
155
                if (!procesarACK) {
 
156
                        return;
 
157
                }
 
158
 
 
159
                ep.Shutdown(Endpoint::OUTPUT);
 
160
 
 
161
                //std::cout << "Message Control ID is = " << msgControlId << std::endl;
 
162
 
 
163
                outputStream.str("");
 
164
 
 
165
                //std::cout << "Connected to: " << std::string(ep.m_remote) << std::endl;
 
166
 
 
167
                unsigned int msgNum = 0;
 
168
 
 
169
                std::list<std::string> mStrings;
 
170
                std::stringstream      inputStream;
 
171
 
 
172
                std::string buff;
 
173
 
 
174
                int bytesReaded = 0;
 
175
 
 
176
                bool started = false;
 
177
                bool pending = true;
 
178
 
 
179
                while( pending && (bytesReaded = ep.Read(-1024, buff))>0 ) {
 
180
                        if (!started) {
 
181
 
 
182
                                std::string::size_type sb_loc = buff.find(START_BLOCK, 0);
 
183
 
 
184
                                if (sb_loc != std::string::npos) {
 
185
 
 
186
                                        started = true;
 
187
 
 
188
                                        mStrings.push_back(std::string());
 
189
 
 
190
                                        msgNum++;
 
191
 
 
192
                                        std::string::size_type eb_loc = buff.find(END_BLOCK, sb_loc+1);
 
193
 
 
194
                                        if (eb_loc != std::string::npos) {
 
195
                                                inputStream << buff.substr(sb_loc + 1, eb_loc - 1 - sb_loc);
 
196
 
 
197
                                                mStrings.back() = inputStream.str();
 
198
                                                inputStream.str("");
 
199
 
 
200
                                                started = false;
 
201
 
 
202
                                                std::string::size_type em_loc = buff.find(END_MSG, eb_loc+1);
 
203
                                                if (em_loc != std::string::npos) {
 
204
                                                        pending = false;
 
205
                                                }
 
206
                                                else {
 
207
                                                        inputStream << buff.substr(eb_loc+1);
 
208
                                                }
 
209
 
 
210
                                        }
 
211
                                        else {
 
212
                                                inputStream << buff.substr(sb_loc + 1);
 
213
                                        }
 
214
                                }
 
215
 
 
216
                        }
 
217
                        else {
 
218
                                std::string::size_type eb_loc = buff.find(END_BLOCK, 0);
 
219
 
 
220
                                if (eb_loc != std::string::npos) {
 
221
                                        inputStream << buff.substr(0, eb_loc - 1);
 
222
                                        started = false;
 
223
 
 
224
                                        mStrings.back() = inputStream.str();
 
225
                                        inputStream.str("");
 
226
 
 
227
                                        std::string::size_type em_loc = buff.find(END_MSG, eb_loc+1);
 
228
                                        if (em_loc != std::string::npos) {
 
229
                                                pending = false;
 
230
                                        }
 
231
                                        else {
 
232
                                                inputStream << buff.substr(eb_loc+1);
 
233
                                        }
 
234
                                }
 
235
                                else {
 
236
                                        inputStream << buff;
 
237
                                }
 
238
                        }
 
239
                }
 
240
                bool confirmado = false;
 
241
                std::list<std::string>::iterator it;
 
242
                unsigned int i;
 
243
                for ( i = 1, it = mStrings.begin(); it != mStrings.end(); i++, it++) {
 
244
                        std::string& s = *it;
 
245
 
 
246
                        if (i != msgNum || !pending) {
 
247
                                //std::cout << "Mensaje :\n" << s << std::endl;
 
248
                                try {
 
249
                                        GIL::Sacyl::Messages::ACKInterpreter ai(GIL::HL7::Message::FromER7(s));
 
250
                                        if (msgControlId != ai.GetReferralMessageControlId()) {
 
251
                                                throw GIL::HL7::HL7Exception(_Std("Error in the logic of confirmation. The control of the message ID does not match recognized"));
 
252
                                        }
 
253
                                        if (!ai.IsSuccess()) {
 
254
                                                std::stringstream errmsg;
 
255
                                                errmsg << _Std("NACK received:") << ai.ERR.GetErrorCodeDescription();
 
256
                                                throw GIL::HL7::HL7Exception(errmsg.str());
 
257
                                        }
 
258
                                        confirmado = true;
 
259
                                }
 
260
                                catch (GIL::HL7::HL7Exception& e)
 
261
                                {
 
262
                                        throw GIL::HL7::HL7Exception(_Std("Failed delivery confirmation:") + e.GetCause(), "COMM");
 
263
                                }
 
264
                                break;
 
265
                        }
 
266
                }
 
267
                if (!confirmado) {
 
268
                        throw GIL::HL7::HL7Exception(_Std("Error in the confirmation of delivery: Delivery is not recognized by the remote end"), "COMM");
 
269
                }
 
270
                //std::cout << "Total: " << ep.GetTotalBytesReaded() << std::endl;*/
 
271
        }
 
272
 
 
273
}