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

« back to all changes in this revision

Viewing changes to src/cadxcore/main/controllers/controladorenviohl7.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
1
/*
2
2
 *  
3
 
 *  $Id: controladorenviohl7.cpp 3893 2011-06-21 13:01:56Z tovar $
 
3
 *  $Id: controladorenviohl7.cpp 4125 2011-09-02 12:22:11Z tovar $
4
4
 *  Ginkgo CADx Project
5
5
 *
6
6
 *  Copyright 2008-10 MetaEmotion S.L. All rights reserved.
16
16
#include <endpoint/endpoint.h>
17
17
#include "controladorenviohl7.h"
18
18
#include "controladorbbddhl7.h"
19
 
#include "controladorextensiones.h"
 
19
#include "controladorcomandos.h"
 
20
#include "controladoreventos.h"
 
21
#include "configurationcontroller.h"
20
22
#include <api/globals.h>
21
23
#include <api/threads/thread.h>
22
24
#include <api/icomando.h>
23
25
#include <api/imodelohl7.h>
24
 
#include <api/iguiasmensajeriasacyl.h>
 
26
#include <eventos/progresocomando.h>
25
27
 
26
28
#define LOGGER "ControladorEnvioHl7"
27
29
#include "controladorlog.h"
28
 
#include "dcmtk/dicomservers.h"
29
30
#include "../entorno.h"
30
 
 
31
 
#include <map>
32
 
 
33
 
#include <ctime>
34
 
 
35
 
#include <wx/xml/xml.h>
36
 
#include <wx/file.h>
37
 
#include <wx/sstream.h>
38
 
#ifndef _WIN32
39
 
#include <signal.h>
40
 
#endif
41
 
#include <wx/tokenzr.h>
42
 
#include <main/controllers/configurationcontroller.h>
43
 
#include <wx/filename.h>
44
 
#include <wx/thread.h>
 
31
#include <commands/sendhl7command.h>
 
32
 
45
33
 
46
34
 
47
35
void GIL::HL7::ControladorEnvioHl7::FreeInstance()
59
47
}
60
48
 
61
49
void GIL::HL7::ControladorEnvioHl7::Arrancar()
62
 
{
63
 
        wxCriticalSectionLocker locker(m_criticalSection);
64
 
        if (m_pInstance == NULL) {
65
 
                m_pInstance = new GIL::HL7::ControladorEnvioHl7();
66
 
                m_pInstance->Create();
67
 
                GNC::GCS::Threading::SetThreadName( m_pInstance->GetId(), "EnvioHL7");
68
 
                wxThreadError error = m_pInstance->Run();
69
 
                if(error != wxTHREAD_NO_ERROR) {
70
 
                        LOG_ERROR("Core/HL7", "Error al arrancar el controlador de envío HL7 error: " << error )
71
 
                } else {
72
 
                        LOG_INFO("Core/HL7", "Arrancando controlador de envío Hl7")
73
 
                }
74
 
        } else {
75
 
                if(!m_pInstance->IsRunning()) {
76
 
                        m_pInstance->Abortar();
77
 
                        m_pInstance->Wait();
78
 
                        delete m_pInstance;
 
50
{       
 
51
        bool boolValue;
 
52
        GNC::GCS::ConfigurationController::Instance()->readBoolGeneral("/GinkgoCore/HCE", "HL7MonitorEnabled", boolValue, true);
 
53
 
 
54
        if (boolValue) {
 
55
                wxCriticalSectionLocker locker(m_criticalSection);
 
56
                if (m_pInstance == NULL) {
79
57
                        m_pInstance = new GIL::HL7::ControladorEnvioHl7();
80
58
                        m_pInstance->Create();
 
59
                        GNC::GCS::Threading::SetThreadName( m_pInstance->GetId(), "EnvioHL7");
81
60
                        wxThreadError error = m_pInstance->Run();
82
61
                        if(error != wxTHREAD_NO_ERROR) {
83
62
                                LOG_ERROR("Core/HL7", "Error al arrancar el controlador de envío HL7 error: " << error )
84
63
                        } else {
85
64
                                LOG_INFO("Core/HL7", "Arrancando controlador de envío Hl7")
86
65
                        }
 
66
                } else {
 
67
                        if(!m_pInstance->IsRunning()) {
 
68
                                m_pInstance->Abortar();
 
69
                                m_pInstance->Wait();
 
70
                                delete m_pInstance;
 
71
                                m_pInstance = new GIL::HL7::ControladorEnvioHl7();
 
72
                                m_pInstance->Create();
 
73
                                wxThreadError error = m_pInstance->Run();
 
74
                                if(error != wxTHREAD_NO_ERROR) {
 
75
                                        LOG_ERROR("Core/HL7", "Error al arrancar el controlador de envío HL7 error: " << error )
 
76
                                } else {
 
77
                                        LOG_INFO("Core/HL7", "Arrancando controlador de envío Hl7")
 
78
                                }
 
79
                        }
87
80
                }
88
81
        }
89
82
}
104
97
//proceso que envia mensajes
105
98
GIL::HL7::ControladorEnvioHl7::ControladorEnvioHl7() : wxThread(wxTHREAD_JOINABLE)
106
99
{
 
100
        GNC::GCS::Eventos::EventoProgresoComando evt;
 
101
        GNC::GCS::ControladorEventos::Instance()->Registrar(this,evt);
107
102
        m_Abortado = false;
108
103
}
109
104
 
114
109
 
115
110
void GIL::HL7::ControladorEnvioHl7::Abortar() {
116
111
        m_Abortado = true;
 
112
        GNC::GCS::ControladorComandos::Instance()->AbortarComandosDeOwner(this);
 
113
        m_semaphore.Post();     
 
114
        m_semaphore.Post();
117
115
}
118
116
 
119
117
bool GIL::HL7::ControladorEnvioHl7::EstaAbortado()
123
121
 
124
122
void* GIL::HL7::ControladorEnvioHl7::Entry()
125
123
{
126
 
        bool error =false;
127
124
        m_Abortado = false;
128
 
        //esperamos a que arranque todo correctamente
129
 
        #ifdef _WIN32
130
 
        Sleep(5000);
131
 
        #else
132
 
        usleep(5000000);
133
 
        #endif
134
125
 
135
 
        while(!TestDestroy() && !m_Abortado && !error) {
136
 
                #ifdef _WIN32
137
 
                Sleep(1000);
138
 
                #else
139
 
                usleep(1000000);
140
 
                #endif
 
126
        while(!TestDestroy() && !m_Abortado) {
141
127
                if(TestDestroy() || m_Abortado){
142
128
            break;
143
129
                }
144
130
                try {
145
 
                        error = !ProcesarMensajes();
 
131
                        //esperamos a que arranque todo correctamente
 
132
                        m_semaphore.WaitTimeout(5000);
 
133
                        TListaMensajes listaMensajes;
 
134
 
 
135
                        GIL::HL7::ControladorBBDDHl7::Instance()->GetMensajesHL7(listaMensajes,true);
 
136
 
 
137
                        if (listaMensajes.size() > 0) {
 
138
                                //launch command...
 
139
                                GADAPI::SendHL7CommandParams* pParams = new GADAPI::SendHL7CommandParams(listaMensajes);
 
140
                                GADAPI::SendHL7Command* pCmd = new GADAPI::SendHL7Command(pParams);
 
141
                                GNC::GCS::ControladorComandos::Instance()->ProcessAsync("Send HL7", pCmd, this);
 
142
                                m_semaphore.Wait();
 
143
                        } 
146
144
                }
147
145
                catch (HL7Exception ex)
148
146
                {
149
147
                        std::ostringstream ostr;
150
148
                        LOG_ERROR("Core/HL7", "Excepción al procesar mensaje:" << ex)
151
 
                        return NULL;
152
149
                }
153
150
        }
154
 
        if(error) {
155
 
                //la instancia ha finalizado, no hace falta borrarla
156
 
                LOG_WARN("Core/HL7", "El Controlador de envío Hl7 ha finalizado debido a un error")
157
 
        } else {
158
 
                LOG_DEBUG("Core/HL7", "El Controlador de envío Hl7 ha finalizado correctamente")
159
 
        }
160
151
        return NULL;
161
152
}
162
153
 
163
 
bool GIL::HL7::ControladorEnvioHl7::ProcesarMensajes() {
164
 
        TListaMensajes listaMensajes;
165
 
 
166
 
        GIL::HL7::ControladorBBDDHl7::Instance()->GetMensajesHL7(listaMensajes,true);
167
 
        for(TListaMensajes::iterator it = listaMensajes.begin(); it!=listaMensajes.end(); it++) {
168
 
                {
169
 
                        std::ostringstream ostr;
170
 
                        LOG_DEBUG("Core/HL7", "Comienza el procesamiento del mensaje "<<(*it).m_id)
171
 
                }
172
 
 
173
 
                try {
174
 
                        switch((*it).m_protocolo) {
175
 
                                case GIL::HL7::IControladorHL7::TP_MLLP:
176
 
                                        EnviarMensajeMLLP((*it).m_mensaje,(*it).m_destino,(*it).m_procesarACK,(*it).m_msgControlId);
177
 
                                        GIL::HL7::ControladorBBDDHl7::Instance()->ActualizarEstadoMensaje((*it).m_id,GIL::HL7::MensajeHL7::TE_Enviado,"");
178
 
                                        LOG_DEBUG("Core/HL7", "Mensaje enviado correctamente")
179
 
                                        break;
180
 
                                default:
181
 
                                        throw HL7Exception(_Std("Unknown protocol"));
182
 
                        }
183
 
                } catch(HL7Exception& ex) {
184
 
                        LOG_ERROR("Core/HL7", "Error al enviar el mensaje:" << ex)
185
 
                        //ha ocurrido un error
186
 
 
187
 
                        //al primer error se para
188
 
                        if (ex.IsFatal()) {
189
 
                                GIL::HL7::ControladorBBDDHl7::Instance()->ActualizarEstadoMensaje((*it).m_id,GIL::HL7::MensajeHL7::TE_Error,ex.GetCause().c_str());
190
 
                                return false;
191
 
                        }
192
 
                        else {
193
 
                                GIL::HL7::ControladorBBDDHl7::Instance()->ActualizarEstadoMensaje((*it).m_id,GIL::HL7::MensajeHL7::TE_Warning,ex.GetCause().c_str());
194
 
                                return true;
195
 
                        }
196
 
                }
197
 
                catch(...) {
198
 
                        LOG_DEBUG("Core/HL7", "Error al enviar el mensaje: Error interno");
199
 
                        GIL::HL7::ControladorBBDDHl7::Instance()->ActualizarEstadoMensaje((*it).m_id, GIL::HL7::MensajeHL7::TE_Error, "Error interno");
200
 
                        return false;
201
 
                }
202
 
 
203
 
        }
204
 
        return true;
205
 
}
206
 
 
207
 
 
208
 
/* Envia el mensaje por MLLP */
209
 
void GIL::HL7::ControladorEnvioHl7::EnviarMensajeMLLP(const std::string& msg, const std::string& url, bool procesarACK, const std::string& msgControlId) const
 
154
void GIL::HL7::ControladorEnvioHl7::ProcesarEvento(GNC::GCS::Eventos::IEvento *evt)
210
155
{
211
 
        const std::string START_BLOCK = "\x0b";
212
 
        const std::string END_BLOCK   = "\x1C";
213
 
        const std::string END_MSG     = "\x0D";
214
 
 
215
 
        #ifndef _WIN32
216
 
        signal(SIGPIPE, SIG_IGN);
217
 
        #endif
218
 
        EndpointAddrlist::g_default_family = AF_INET;
219
 
 
220
 
        Endpoint::Initialize();
221
 
 
222
 
        Endpoint ep(TCP | CLIENT, url);
223
 
 
224
 
        if (!ep) {
225
 
                throw HL7Exception(_Std("Failed to start connection") + ep.m_error_str, "COMM");
226
 
        }
227
 
 
228
 
        std::stringstream outputStream;
229
 
        outputStream << START_BLOCK << msg << END_BLOCK << END_MSG;
230
 
 
231
 
        long nbytes = ep.Write(outputStream.str());
232
 
        if (nbytes != (long)outputStream.str().size()) {
233
 
                std::stringstream errmsg;
234
 
                if (nbytes == -1) {
235
 
                        errmsg << _Std("Error sending message:") << ep.m_error_str;
236
 
                }
237
 
                else {
238
 
                        errmsg << _Std("Error sending message. It was sent ") << nbytes << _Std(" bytes from a total of ") << outputStream;
239
 
                }
240
 
                throw HL7Exception(errmsg.str(), "COMM");
241
 
        }
242
 
 
243
 
        if (!procesarACK) {
 
156
        GNC::GCS::Eventos::EventoProgresoComando* pEvt = dynamic_cast<GNC::GCS::Eventos::EventoProgresoComando*> (evt);
 
157
        GNC::GCS::IComando* pCmd = pEvt->GetComando();
 
158
        if (pEvt == NULL  || pEvt->GetComando() == NULL) {
244
159
                return;
245
160
        }
246
 
 
247
 
        ep.Shutdown(Endpoint::OUTPUT);
248
 
 
249
 
        //std::cout << "Message Control ID is = " << msgControlId << std::endl;
250
 
 
251
 
        outputStream.str("");
252
 
 
253
 
        //std::cout << "Connected to: " << std::string(ep.m_remote) << std::endl;
254
 
 
255
 
        unsigned int msgNum = 0;
256
 
 
257
 
        std::list<std::string> mStrings;
258
 
        std::stringstream      inputStream;
259
 
 
260
 
        std::string buff;
261
 
 
262
 
        int bytesReaded = 0;
263
 
 
264
 
        bool started = false;
265
 
        bool pending = true;
266
 
 
267
 
        while( pending && (bytesReaded = ep.Read(-1024, buff))>0 ) {
268
 
                if (!started) {
269
 
 
270
 
                        std::string::size_type sb_loc = buff.find(START_BLOCK, 0);
271
 
 
272
 
                        if (sb_loc != std::string::npos) {
273
 
 
274
 
                                started = true;
275
 
 
276
 
                                mStrings.push_back(std::string());
277
 
 
278
 
                                msgNum++;
279
 
 
280
 
                                std::string::size_type eb_loc = buff.find(END_BLOCK, sb_loc+1);
281
 
 
282
 
                                if (eb_loc != std::string::npos) {
283
 
                                        inputStream << buff.substr(sb_loc + 1, eb_loc - 1 - sb_loc);
284
 
 
285
 
                                        mStrings.back() = inputStream.str();
286
 
                                        inputStream.str("");
287
 
 
288
 
                                        started = false;
289
 
 
290
 
                                        std::string::size_type em_loc = buff.find(END_MSG, eb_loc+1);
291
 
                                        if (em_loc != std::string::npos) {
292
 
                                                pending = false;
293
 
                                        }
294
 
                                        else {
295
 
                                                inputStream << buff.substr(eb_loc+1);
296
 
                                        }
297
 
 
298
 
                                }
299
 
                                else {
300
 
                                        inputStream << buff.substr(sb_loc + 1);
301
 
                                }
302
 
                        }
303
 
 
304
 
                }
305
 
                else {
306
 
                        std::string::size_type eb_loc = buff.find(END_BLOCK, 0);
307
 
 
308
 
                        if (eb_loc != std::string::npos) {
309
 
                                inputStream << buff.substr(0, eb_loc - 1);
310
 
                                started = false;
311
 
 
312
 
                                mStrings.back() = inputStream.str();
313
 
                                inputStream.str("");
314
 
 
315
 
                                std::string::size_type em_loc = buff.find(END_MSG, eb_loc+1);
316
 
                                if (em_loc != std::string::npos) {
317
 
                                        pending = false;
318
 
                                }
319
 
                                else {
320
 
                                        inputStream << buff.substr(eb_loc+1);
321
 
                                }
322
 
                        }
323
 
                        else {
324
 
                                inputStream << buff;
325
 
                        }
326
 
                }
327
 
        }
328
 
        bool confirmado = false;
329
 
        std::list<std::string>::iterator it;
330
 
        unsigned int i;
331
 
        for ( i = 1, it = mStrings.begin(); it != mStrings.end(); i++, it++) {
332
 
                std::string& s = *it;
333
 
 
334
 
                if (i != msgNum || !pending) {
335
 
                        //std::cout << "Mensaje :\n" << s << std::endl;
336
 
                        try {
337
 
                                GIL::Sacyl::Messages::ACKInterpreter ai(GIL::HL7::Message::FromER7(s));
338
 
                                if (msgControlId != ai.GetReferralMessageControlId()) {
339
 
                                        throw HL7Exception(_Std("Error in the logic of confirmation. The control of the message ID does not match recognized"));
340
 
                                }
341
 
                                if (!ai.IsSuccess()) {
342
 
                                        std::stringstream errmsg;
343
 
                                        errmsg << _Std("NACK received:") << ai.ERR.GetErrorCodeDescription();
344
 
                                        throw HL7Exception(errmsg.str());
345
 
                                }
346
 
                                confirmado = true;
347
 
                        }
348
 
                        catch (HL7Exception& e)
349
 
                        {
350
 
                                throw HL7Exception(_Std("Failed delivery confirmation:") + e.GetCause(), "COMM");
351
 
                        }
352
 
                        break;
353
 
                }
354
 
        }
355
 
        if (!confirmado) {
356
 
                throw HL7Exception(_Std("Error in the confirmation of delivery: Delivery is not recognized by the remote end"), "COMM");
357
 
        }
358
 
        //std::cout << "Total: " << ep.GetTotalBytesReaded() << std::endl;*/
 
161
        if (pEvt->GetTipo() == GNC::GCS::Eventos::EventoProgresoComando::TEP_Finalizado)
 
162
        {
 
163
                GADAPI::SendHL7Command* pCmdSend = dynamic_cast< GADAPI::SendHL7Command * > (pCmd);
 
164
                if (pCmdSend != NULL)
 
165
                {
 
166
                        m_semaphore.Post();
 
167
                }
 
168
        }       
359
169
}
 
170