sp_fr: implement response flow (#33838)
This commit is contained in:
parent
a6b7df1192
commit
2497cab25e
|
@ -170,16 +170,20 @@ class Resource(BaseResource):
|
|||
try:
|
||||
move, error = handler()
|
||||
except Exception:
|
||||
count -= 1
|
||||
self.logger.exception('handling of file "%s" failed', filename)
|
||||
# sftp.rename(filename, 'FAILED/' + filename)
|
||||
sftp.rename(filename, 'FAILED/' + filename)
|
||||
else:
|
||||
if move and error:
|
||||
count -= 1
|
||||
self.logger.error('handling of file "%s" failed: %s', filename, error)
|
||||
# sftp.rename(filename, 'FAILED/' + filename)
|
||||
sftp.rename(filename, 'FAILED/' + filename)
|
||||
else:
|
||||
if error:
|
||||
count -= 1
|
||||
self.logger.warning('handling of file "%s" failed: %s', filename, error)
|
||||
elif move:
|
||||
count -= 1
|
||||
sftp.rename(filename, 'DONE/' + filename)
|
||||
if not count:
|
||||
break
|
||||
|
@ -226,6 +230,7 @@ class Resource(BaseResource):
|
|||
return False, 'error during response to service-public.fr %r' % e
|
||||
self.request.state = Request.STATE_RETURNED
|
||||
self.request.save()
|
||||
self.resource.logger.info('%s responded, closed', self.request.filename)
|
||||
return True, None
|
||||
|
||||
def process(self, fd):
|
||||
|
@ -330,7 +335,18 @@ class Resource(BaseResource):
|
|||
return submitter.result.backoffice_url
|
||||
|
||||
def response(self):
|
||||
raise NotImplementedError
|
||||
with self.resource.output_sftp.client() as client:
|
||||
with client.open(self.request.response_zip_filename, mode='w') as fd:
|
||||
self.request.build_response_zip(
|
||||
fd,
|
||||
etat='100',
|
||||
commentaire=u'Demande transmise à la collectivité')
|
||||
with self.resource.input_sftp.client() as client:
|
||||
with client.open('DONE/' + self.request.response_zip_filename, mode='w') as fd:
|
||||
self.request.build_response_zip(
|
||||
fd,
|
||||
etat='100',
|
||||
commentaire=u'Demande transmise à la collectivité')
|
||||
|
||||
def get_data(self, data, name):
|
||||
# prevent error in manual mapping
|
||||
|
@ -626,8 +642,8 @@ class Request(models.Model):
|
|||
STATE_ERROR = 'error'
|
||||
STATES = [
|
||||
(STATE_RECEIVED, _('Received')),
|
||||
(STATE_TRANSFERED, _('Transfered')),
|
||||
(STATE_ERROR, _('Transfered')),
|
||||
(STATE_TRANSFERED, _('Transferred')),
|
||||
(STATE_ERROR, _('Error')),
|
||||
(STATE_RETURNED, _('Returned')),
|
||||
]
|
||||
|
||||
|
@ -668,6 +684,113 @@ class Request(models.Model):
|
|||
self.resource.logger.error('could not delete %s', self.archive)
|
||||
return super(Request, self).delete(*args, **kwargs)
|
||||
|
||||
@property
|
||||
def message_xml(self):
|
||||
# FileField can be closed, or open, you never know, and used as a
|
||||
# contextmanager, __enter__ does not re-open/re-seek(0) it :/
|
||||
self.archive.open()
|
||||
|
||||
with self.archive as fd:
|
||||
with zipfile.ZipFile(fd) as archive:
|
||||
with archive.open('message.xml') as message_xml_fd:
|
||||
s = message_xml_fd.read()
|
||||
return ET.fromstring(s)
|
||||
|
||||
@property
|
||||
def id_enveloppe(self):
|
||||
message_xml = self.message_xml
|
||||
ns = {
|
||||
'pec': 'http://finances.gouv.fr/dgme/pec/message/v1',
|
||||
'mdel': 'http://finances.gouv.fr/dgme/gf/composants/teledemarchexml/donnee/metier'
|
||||
}
|
||||
return message_xml.find('.//{%(pec)s}MessageId' % ns).text.split()[1]
|
||||
|
||||
def build_message_xml_retour(self, etat, commentaire):
|
||||
message_xml = self.message_xml
|
||||
|
||||
ns = {
|
||||
'pec': 'http://finances.gouv.fr/dgme/pec/message/v1',
|
||||
'mdel': 'http://finances.gouv.fr/dgme/gf/composants/teledemarchexml/donnee/metier'
|
||||
}
|
||||
|
||||
template = '''<ns2:Message xmlns:ns2="http://finances.gouv.fr/dgme/pec/message/v1" xmlns="http://finances.gouv.fr/dgme/gf/composants/teledemarchexml/donnee/metier">
|
||||
<ns2:Header>
|
||||
<ns2:Routing>
|
||||
<ns2:MessageId/>
|
||||
<ns2:RefToMessageId/>
|
||||
<ns2:FlowType/>
|
||||
<ns2:Sender/>
|
||||
<ns2:Recipients>
|
||||
<ns2:Recipient/>
|
||||
</ns2:Recipients>
|
||||
</ns2:Routing>
|
||||
<ns2:Security>
|
||||
<ns2:Horodatage>false</ns2:Horodatage>
|
||||
</ns2:Security>
|
||||
</ns2:Header>
|
||||
<ns2:Body>
|
||||
<ns2:Content><ns2:Retour>
|
||||
<ns2:Enveloppe>
|
||||
<ns2:NumeroTeledemarche/>
|
||||
<ns2:MotDePasse/>
|
||||
</ns2:Enveloppe>
|
||||
<ns2:Instruction>
|
||||
<ns2:Maj>
|
||||
<ns2:Etat/>
|
||||
<ns2:Commentaire/>
|
||||
</ns2:Maj>
|
||||
</ns2:Instruction>
|
||||
</ns2:Retour>
|
||||
</ns2:Content>
|
||||
</ns2:Body>
|
||||
</ns2:Message>''' # NOQA E501
|
||||
|
||||
response = ET.XML(template)
|
||||
|
||||
message_id = message_xml.find('.//{%(pec)s}MessageId' % ns).text
|
||||
# maybe could work with str(uuid.uuid4().hex), which would be more unique, we will never know
|
||||
response.find('.//{%(pec)s}MessageId' % ns).text = 'RET-1-' + message_id
|
||||
response.find('.//{%(pec)s}RefToMessageId' % ns).text = message_id
|
||||
response.find('.//{%(pec)s}FlowType' % ns).text = message_xml.find('.//{%(pec)s}FlowType' % ns).text
|
||||
response.find('.//{%(pec)s}Sender' % ns).extend(
|
||||
message_xml.find('.//{%(pec)s}Recipient' % ns))
|
||||
response.find('.//{%(pec)s}Recipient' % ns).extend(
|
||||
message_xml.find('.//{%(pec)s}Sender' % ns))
|
||||
|
||||
response.find('.//{%(pec)s}FlowType' % ns).text = message_xml.find('.//{%(pec)s}FlowType' % ns).text
|
||||
|
||||
# Strangely the same node in the response does not have the same
|
||||
# namespace as the node in the request, whatever...
|
||||
response.find('.//{%(pec)s}NumeroTeledemarche' % ns).text = message_xml.find(
|
||||
'.//{%(mdel)s}NumeroTeledemarche' % ns).text
|
||||
response.find('.//{%(pec)s}MotDePasse' % ns).text = message_xml.find('.//{%(mdel)s}MotDePasse' % ns).text
|
||||
response.find('.//{%(pec)s}Etat' % ns).text = '100'
|
||||
response.find('.//{%(pec)s}Commentaire' % ns).text = u'Dossier transmis à la collectivité'
|
||||
return response
|
||||
|
||||
def build_response_zip(self, fd_or_filename, etat, commentaire):
|
||||
with zipfile.ZipFile(fd_or_filename, 'w') as archive:
|
||||
message_xml = self.build_message_xml_retour(
|
||||
etat=etat, commentaire=commentaire)
|
||||
archive.writestr('message.xml',
|
||||
'<?xml version="1.0" encoding="UTF-8" standalone="yes"?>'
|
||||
+ ET.tostring(message_xml, encoding='utf-8'))
|
||||
|
||||
@property
|
||||
def response_zip_filename(self):
|
||||
m = FILE_PATTERN.match(self.filename)
|
||||
|
||||
numero_teledossier = m.group('identifier')
|
||||
code_demarche = m.group('procedure')
|
||||
id_enveloppe = self.id_enveloppe
|
||||
numero_sequence = '1'
|
||||
|
||||
return '%s-%s-%s-%s.zip' % (
|
||||
numero_teledossier,
|
||||
code_demarche,
|
||||
id_enveloppe,
|
||||
numero_sequence)
|
||||
|
||||
class Meta:
|
||||
verbose_name = _('MDEL request')
|
||||
verbose_name_plural = _('MDEL requests')
|
||||
|
|
Loading…
Reference in New Issue