ASG
IBM
Zystems
Cressida
Icon
Netflexity
 
  MQSeries.net
Search  Search       Tech Exchange      Education      Certifications      Library      Info Center      SupportPacs      LinkedIn  Search  Search                                                                   FAQ  FAQ   Usergroups  Usergroups
 
Register  ::  Log in Log in to check your private messages
 
RSS Feed - WebSphere MQ Support RSS Feed - Message Broker Support

MQSeries.net Forum Index » WebSphere Message Broker (ACE) Support » Zip file as email attachment

Post new topic  Reply to topic Goto page 1, 2  Next
 Zip file as email attachment « View previous topic :: View next topic » 
Author Message
Buzz Lightyear
PostPosted: Tue Jun 13, 2017 3:32 am    Post subject: Zip file as an email attachment. Reply with quote

Newbie

Joined: 29 May 2017
Posts: 9

Reviving a very old thread here and hoping to find the answer.

I am trying to send out an email with a zip attachment through my message flow application deployed on WMB 7.0.3. The issue that I face is that the zip file attachment is sent through the email; I can open the zip file; but inside it, I do not see any files.

Below is the code snippet that I use to create the zip file. This is an external Java procedure that I call through from my ESQL code.

Code:

   public static void createZipFile(MbElement[] fileSetRef) {

      ByteArrayOutputStream baos = new ByteArrayOutputStream();
      ZipOutputStream zos = new ZipOutputStream(baos);

      byte[] packedData = null;

      MbElement child = fileSetRef[0].getFirstChild();   // File element.

      while(true) {
          // navigate through the MbElement tree

         String fName = (String) child.getValueAsString();    // File Name
         byte[] data = (byte[]) nxtChild.getValue();   // BLOB

         ZipEntry ze = new ZipEntry(fName);
         zos.putNextEntry(ze);

         zos.write(data, 0, data.length);
         zos.closeEntry();

         // loop through all child nodes

      } // loop ends.

      zos.finish();
      zos.close();
            
      packedData = baos.toByteArray();
            
      MbElement packedDataElement = fileSetRef[0].getFirstChild().createElementAfter(MbBLOB.PARSER_NAME);
      packedDataElement.setName("PackedData");
      packedDataElement.setValue(packedData);

   } // method ends


Below is the ESQL code to call the above Java function.

Code:

   DECLARE refFileSet REFERENCE TO Environment.Variables.FileSet; -- contains File fields. File field contains FileName and Data (BLOB) fields.
   CALL CreateZipFile(refFileSet);

   CREATE LASTCHILD OF OutputRoot.MIME.Parts TYPE Name NAME 'Part';
   DECLARE mimePart REFERENCE TO OutputRoot.MIME.Parts.Part[<];
         
   CREATE FIELD mimePart."Content-Type" TYPE NameValue VALUE 'application/zip; name=log.zip';
   CREATE FIELD mimePart."Content-Transfer-Encoding" TYPE NameValue VALUE '8bit';
            
   CREATE LASTCHILD OF mimePart TYPE Name NAME 'Data';
   CREATE LASTCHILD OF mimePart.Data DOMAIN('BLOB');

   SET mimePart .Data.BLOB.BLOB = refFileSet.PackedData;



I can confirm that the Java code works. Writing the byte array "packedData" to file output file stream (all this within the Java code), results in a file with the zipped contents. Its only then the control returns back to ESQL module and the BLOB is set in the output MIME tree that the details are lost.

What am I doing wrong here ?
Back to top
View user's profile Send private message
mqjeff
PostPosted: Tue Jun 13, 2017 3:59 am    Post subject: Re: Zip file as an email attachment. Reply with quote

Grand Master

Joined: 25 Jun 2008
Posts: 17447

Buzz Lightyear wrote:
Reviving a very old thread here and hoping to find the answer.




Perhaps a moderator will split your question into a new thread, where it should be... you could then edit it to have a link to this old thread.

Otherwisee, what does it show using the debugger?
_________________
chmod -R ugo-wx /
Back to top
View user's profile Send private message
Vitor
PostPosted: Tue Jun 13, 2017 4:38 am    Post subject: Re: Zip file as an email attachment. Reply with quote

Grand High Poobah

Joined: 11 Nov 2005
Posts: 26093
Location: Texas, USA

mqjeff wrote:
Buzz Lightyear wrote:
Reviving a very old thread here and hoping to find the answer.




Perhaps a moderator will split your question into a new thread, where it should be...


Done.

mqjeff wrote:
you could then edit it to have a link to this old thread.


Including this at no extra charge.

mqjeff wrote:
Otherwisee, what does it show using the debugger?


Better still, what does the user trace (in conjunction with a Trace node just before the EmailOutput node) say about the message tree?
_________________
Honesty is the best policy.
Insanity is the best defence.
Back to top
View user's profile Send private message
fjb_saper
PostPosted: Tue Jun 13, 2017 4:52 am    Post subject: Reply with quote

Grand High Poobah

Joined: 18 Nov 2003
Posts: 20696
Location: LI,NY

I would look at your static Java function. I'd expect it to may be return an MbElement?
It looks to me that you may be just modifying the one being passed but then it needs to be passed by reference and not by value...
_________________
MQ & Broker admin
Back to top
View user's profile Send private message Send e-mail
Buzz Lightyear
PostPosted: Tue Jun 13, 2017 5:19 am    Post subject: Reply with quote

Newbie

Joined: 29 May 2017
Posts: 9

@Vitor: Thank you for spawning a new thread.

Well, the debugger shows the BLOB data in the reference that was passed to the Java function. This is later set in the MIME which works out well as the email carries that attachment. Its a zip ! It opens ! But no file contents, which is weird !

@fjp_saper: Yes, the CreateZipFile works on the MbElement. Below is the ESQL declaration for it.

Code:

CREATE PROCEDURE CreateZipFile (INOUT fileSet REFERENCE)
LANGUAGE JAVA
EXTERNAL NAME "com.examples.utils.ZipFileHelper.createZipFile";


Below is the way I call this function.

Code:

   DECLARE refFileSet REFERENCE TO Environment.Variables.FileSet;
   CALL CreateZipFile(refFileSet);


Subsequent code simply uses this refFileSet reference variable. I didn't quite understand the "passed by reference and not by value" remark.
Do I need to do anything differently ?
Back to top
View user's profile Send private message
fjb_saper
PostPosted: Tue Jun 13, 2017 5:28 am    Post subject: Reply with quote

Grand High Poobah

Joined: 18 Nov 2003
Posts: 20696
Location: LI,NY

Java parameters are only passed by value. So your INOUT has no meaning if there is not a return (MbElement ) parmname statement in Java.

When passing MbElement you're in fact passing an non mutable pointer to MbElement. That means that you can manipulate the content of the class by using its method, however you cannot change the pointer or instantiate the variable by passing it a new pointer...

So myobject.someMethod(parms) will change the content of the class as seen from the calling program...

myobject = xyz will have no effect to the content or pointer of myobject as far as the calling program is concerned...

Have fun
_________________
MQ & Broker admin
Back to top
View user's profile Send private message Send e-mail
Buzz Lightyear
PostPosted: Tue Jun 13, 2017 8:11 am    Post subject: Reply with quote

Newbie

Joined: 29 May 2017
Posts: 9

Not sure I understood. Indeed Java parameters are pass by value. But those values are addresses. Hence something like the below should work.
Code:

public static void createZipFile(MbElement[] fileSetRef) {
      ...
      ...
      ...
      MbElement packedDataElement = fileSetRef[0].getFirstChild().createElementAfter(MbBLOB.PARSER_NAME);
      packedDataElement.setName("PackedData");
      packedDataElement.setValue(packedData);

   } // method ends
}


And it does work. Below is the before and after of the reference passed between ESQL and Java function as seen in the debugger.

Before:
Quote:

refFileSet
File
FileName:CHARACTER:file1.xml
DataBinary:BLOB:[B@7c127c12
File
FileName:CHARACTER:file2.xml
DataBinary:BLOB:[B@3140314
File
FileName:CHARACTER:file3.xml
DataBinary:BLOB:[B@e5e0e5e
File
FileName:CHARACTER:file4.xml
DataBinary:BLOB:[B@19a619a6
File
FileName:CHARACTER:file5.xml
DataBinary:BLOB:[B@24f024f0


After:
Quote:

refFileSet
File
FileName:CHARACTER:file1.xml
DataBinary:BLOB:[B@55845584
PackedData:BLOB:[B@5a825a82
File
FileName:CHARACTER:file2.xml
DataBinary:BLOB:[B@645a645a
File
FileName:CHARACTER:file3.xml
DataBinary:BLOB:[B@6e1a6e1a
File
FileName:CHARACTER:file4.xml
DataBinary:BLOB:[B@79627962
File
FileName:CHARACTER:file5.xml
DataBinary:BLOB:[B@4b804b8


Note that the BLOB addresses have changed.

I surely cannot have a returns (MbElement ) parameter name statement in the Java code as this would require me to modify my function signature to
Code:
public static MbElement createZipFile(MbElement[] fileSetRef) {


Doing so would return the following error.
Code:

RecoverableException
      File:CHARACTER:/build/S700_P/src/DataFlowEngine/ImbRdl/ImbRdlExternalJava.cpp
      Line:INTEGER:1123
      Function:CHARACTER:ESQL2JavaMethodResolver::decodeReturnStatus
      Type:CHARACTER:
      Name:CHARACTER:
      Label:CHARACTER:
      Catalog:CHARACTER:BIPmsgs
      Severity:INTEGER:3
      Number:INTEGER:2928
      Text:CHARACTER:The Java return type does not match the ESQL return type
      Insert
            Type:INTEGER:5
            Text:CHARACTER:com.examples.utils.ZipFileHelper.createZipFile


Beats me !
Back to top
View user's profile Send private message
fjb_saper
PostPosted: Tue Jun 13, 2017 9:22 am    Post subject: Reply with quote

Grand High Poobah

Joined: 18 Nov 2003
Posts: 20696
Location: LI,NY

What I meant to say is that you have defined Filesetref as INOUT whereas it is an IN parameter... There is no out...
_________________
MQ & Broker admin
Back to top
View user's profile Send private message Send e-mail
Buzz Lightyear
PostPosted: Tue Jun 13, 2017 9:50 am    Post subject: Reply with quote

Newbie

Joined: 29 May 2017
Posts: 9

How should the MbElement be returned from the Java function to the caller ESQL, then ? Return (MBElement variable) statement wont work without changing the Java function signature. Also https://www.ibm.com/support/knowledgecenter/en/SSMKHH_9.0.0/com.ibm.etools.mft.doc/ak20708_.htm states that one cannot have MbElement as the return type of the Java function.
Back to top
View user's profile Send private message
fjb_saper
PostPosted: Tue Jun 13, 2017 12:42 pm    Post subject: Reply with quote

Grand High Poobah

Joined: 18 Nov 2003
Posts: 20696
Location: LI,NY

Buzz Lightyear wrote:
How should the MbElement be returned from the Java function to the caller ESQL, then ? Return (MBElement variable) statement wont work without changing the Java function signature. Also https://www.ibm.com/support/knowledgecenter/en/SSMKHH_9.0.0/com.ibm.etools.mft.doc/ak20708_.htm states that one cannot have MbElement as the return type of the Java function.


The point here is that you don't return it as you did not change it. What you did was manipulate it's contents... So an IN would have been sufficient...
Same as using a procedure in ESQL and passing a reference. As long as you never "MOVE" the reference...

For INOUT you should have used MbElement[] as signature for the return type...
[edit] He did use the correct signatures however there is no reference change of MbElelment[0] and as such clarification should have shown that it is an IN parameter only and not INOUT and have given a different signature to Java. [/edit]

And the point was that you're not returning anything from your Java function as shown by the void in your signature.
[edit]The point was that the pointer MbElement[0] never got changed... so why an INOUT? [/edit]
_________________
MQ & Broker admin


Last edited by fjb_saper on Thu Jun 15, 2017 2:18 am; edited 2 times in total
Back to top
View user's profile Send private message Send e-mail
Buzz Lightyear
PostPosted: Wed Jun 14, 2017 10:17 am    Post subject: Reply with quote

Newbie

Joined: 29 May 2017
Posts: 9

Changing the signature to the one below resulted in an exception. The method was not found.
Code:

public static MbElement[] createZipFile(MbElement[] fileSetRef) {
...
...
}


I am really sorry about this, but can you please illustrate with an example ? By adding a new element "PackedData" of BLOB domain to the reference tree am I not changing the reference ? Or is it manipulating the tree ? I don't seem to understand the nuance there-in !

Are you suggesting that I create a PackedData element in the ESQL code before passing the reference to the Java function ?
[/quote]
Back to top
View user's profile Send private message
mqjeff
PostPosted: Wed Jun 14, 2017 11:44 am    Post subject: Reply with quote

Grand Master

Joined: 25 Jun 2008
Posts: 17447

Despite what my esteemed colleague says, I'm going to state that your original procedure definition and method call were correct.

You should make that call either a) in a separate compute node or b) with a propagate statement that points to an out terminal that goes to a trace node.

Basically, pass the contents of your message tree after the java procedure, but before anything else, to a trace node - ideally pointing to user trace.

I would also do a trace node output without the attachment to make sure you like the MIME tree.

Then you can see what you get back.

You might also be having CCSID issues, where the zip file data is being transformed into text inappropriately.
_________________
chmod -R ugo-wx /
Back to top
View user's profile Send private message
fjb_saper
PostPosted: Wed Jun 14, 2017 7:40 pm    Post subject: Reply with quote

Grand High Poobah

Joined: 18 Nov 2003
Posts: 20696
Location: LI,NY

Buzz Lightyear wrote:
Changing the signature to the one below resulted in an exception. The method was not found.
Code:

public static MbElement[] createZipFile(MbElement[] fileSetRef) {
...
...
}


I am really sorry about this, but can you please illustrate with an example ? By adding a new element "PackedData" of BLOB domain to the reference tree am I not changing the reference ? Or is it manipulating the tree ? I don't seem to understand the nuance there-in !

Are you suggesting that I create a PackedData element in the ESQL code before passing the reference to the Java function ?

Agreed the nuance is a little bit pedantic. What I meant was
A) Don't touch your Java procedure
B) Keep the ESQL signature as INOUT
C) Verify that it works as expected.
D) Specify in the comments that you are not changing the pointer for the reference.

The reason that you are asked to pass the INOUT parameter as MbElement[] is that you would now be able to change the content of the array and put a different instance of MBElement into the array, thus enabling the MbElement to be changed (i.e. reference to be Moved).

For what goes on beyond you need like Jeff said to add some logging to look at the tree. You may also have to byte64 encode your zip BLOB... before creating the attachment. This would be to mitigate any CCSID problem as I'd expect all to be UTF-8 (email protocol) ...

Have fun
_________________
MQ & Broker admin
Back to top
View user's profile Send private message Send e-mail
Buzz Lightyear
PostPosted: Thu Jun 15, 2017 5:03 am    Post subject: Reply with quote

Newbie

Joined: 29 May 2017
Posts: 9

Thank you mqJeff for the intervention.

I rolled-back my CreateZipFile function signature and ESQL declaration to the one I started with. The Java function returned a BLOB as before. But this time around I was able to store it in a file on the file system using the FileOutputNode (I modified my flow a bit for this). The file created was a valid zip file. Its opened and I could see the contents in there. What did the trick were these two seemingly innocuous statements.

Code:

SET OutputRoot.Properties.Encoding = 273;
SET OutputRoot.Properties.CodedCharSetId = 1208;


However the mail attachment continues to be an empty zip. Below is the trace details (edited for brevity!).

Quote:


(0x01000000:Name):EmailOutputHeader = ( ['EMAILHDR' : 0x11bb815f0]
(0x03000000:NameValue):To = 'john.doe@who.where.com' (CHARACTER)
(0x03000000:NameValue):Cc = 'jane.doe@who.where.com' (CHARACTER)
(0x03000000:NameValue):From = 'doe@who.where.com' (CHARACTER)
(0x03000000:NameValue):Subject = 'Hello World !' (CHARACTER)
)
(0x01000000:Name):MIME = ( ['MIME' : 0x11bb84970]
(0x03000000:NameValue):Content-Type = 'multipart/related; boundary=bf2c9c7a-51c7-11e7-83a2-000000000000' (CHARACTER)
(0x03000000:NameValue):Content-ID = 'bf2ca45e-51c7-11e7-83a2-000000000000' (CHARACTER)
(0x01000000:Name ):Parts = (
(0x01000000:Name):Part = (
(0x03000000:NameValue):Content-Type = 'text/html; charset=UTF-8' (CHARACTER)
(0x03000000:NameValue):Content-Transfer-Encoding = '8bit' (CHARACTER)
(0x01000000:Name ):Data = (
(0x01000000:Name):BLOB = ( ['none' : 0x11bb85cb0]
(0x03000000:NameValue):BLOB = X'3c68746d686561643e047970620636f687474702d6c3e0a3c65717569766c3e0a3c3d22436f642d547970

... more bytes


' (BLOB)
)
)
)
(0x01000000:Name):Part = (
(0x03000000:NameValue):Content-Type = 'application/zip; name=application-logs.zip' (CHARACTER)
(0x03000000:NameValue):Content-Transfer-Encoding = '8bit' (CHARACTER)
(0x01000000:Name ):Data = (
(0x03000000:NameValue):BLOB = X'504b03041400080008004091cf4a000000000000000000000000280000004149535f534150494e5f4d42535f4d465f32303133313232325f303132333031353332312e786d

... more bytes


00040058010000fe1d00000000' (BLOB)
)
)
)
)
)




I confirmed that the attachment BLOB produced the valid zip file (using the FileOutputNode). Looks like I still need do something with the BLOB encoding specifically for email as indicated by fjb_saper.

I will get back to this thread with a solution or after losing a bit more of my hair !
Back to top
View user's profile Send private message
mqjeff
PostPosted: Thu Jun 15, 2017 6:32 am    Post subject: Reply with quote

Grand Master

Joined: 25 Jun 2008
Posts: 17447

It kinda looks like the BLOB data is in a basic conversion ("X'....") instead of being in a real translation.

Try ASBITSTREAM with the CCSID/Encoding you found, like
Code:

   SET mimePart .Data.BLOB.BLOB = ASBITSTREAM(refFileSet.PackedData ... );

_________________
chmod -R ugo-wx /
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic  Reply to topic Goto page 1, 2  Next Page 1 of 2

MQSeries.net Forum Index » WebSphere Message Broker (ACE) Support » Zip file as email attachment
Jump to:  



You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
Protected by Anti-Spam ACP
 
 


Theme by Dustin Baccetti
Powered by phpBB © 2001, 2002 phpBB Group

Copyright © MQSeries.net. All rights reserved.