Monday, June 27, 2016

New Directions

It has been a long time since I have posted any blog updates, so I wanted to give an update on what is happening in my world.
As I write, it seems like a very long time since I attended IBM Connect 2016 this past January/February.  It was a great conference and I came home from it very optimistic and fired up about the future.  I was nearly 100% sure that I would soon be moving on from my current position as a contract XPages developer at Navy Federal and finding a new position somewhere else as a Notes Domino/XPages developer.  I had several encouraging meetings at the conference and I left sure that one of them would work out for me.
In March, I came very close to being hired for one particular position that would have had me working with some of the best XPages developers in the business.  After a very positive interview, that job fell through due to factors beyond mine and their control.   It's also worth noting that in the last year, I started to notice a decline in the number of XPages job postings.  It seems like a year ago, there were always 5-7 postings out there, sometimes more, sometimes less.  It seems now the only postings are in the DC or New York areas, two places in which I do not wish to move.
While I love the platform and have a long and positive history with Notes, I knew and have known for years that it was only a matter of time before I would need to move on to other technologies. Years ago in the mid 2000’s I immersed myself in Java with the intent of moving in that direction.  I thought that my ideal job would be where I can get in the door as a Notes developer and then transition to Java without taking the big pay cut that would occur if I went the Junior Developer route.  This was my plan, but I kept getting interesting and well-paying Notes developer jobs.  When XPages came out, I immersed myself in learning it, and found that my prior Java studies have paid off greatly in that area.  While I like backend java, I really loved front end work and I think I am a decent UI designer.
In early April, I found myself working as contract developer and working on doing mostly Notes development.  For some reason, Navy Federal has decided not to create any more XPages projects so most of the work would be maintenance projects on existing Notes client applications.  I was not getting serious interest for other jobs developing XPages despite the honor of being an IBM Champion.  Meanwhile my manager, for whom I have a lot of respect, continued to encourage me to apply for a full time Java developer position in which I would still report to him.  After much reflection, discussion, and prayer I did decide that I would move forward and accept a position if it was offered.  
At the end of April I accepted a full time position as an ISD Developer III and will be working on Java and whatever else they ask me to do.  I hope to get to eventually get to work with the front end again, but for now it will be mostly back end.  I still might work occasionally with Notes if they assign me those projects.  It is very unlikely that I will work with XPages again any time soon.
It is not without some sadness that I move on from the Yellow Bubble (Notes Community).  Even though I am moving on, I hope to maintain contact with the friends I have made.  I remain extremely honored to have been named an IBM Champion for 2016. In some ways it feels like going out on top.  I look back to my goal of ten years ago of transitioning to a Java developer internally from Notes, and realize that I have obtained that goal over 10-12 years after making it.
After I accepted the job but prior to my start date, Navy Federal was kind enough to let me take six weeks of leave to catch up on family visits and move the last of my possessions in storage from Utah to Florida.  Despite many miles of driving, we had great visits in Texas, Utah, Missouri, Minnesota, Indiana, Pennsylvania, and Virginia.  I also got to add 62 miles towards my goal of completing the Appalachian Trail in my lifetime.
So as of today, Monday June 27, I am now a Navy Federal full time employee.  I plan to stay for a while and we will settle here in the Florida panhandle. I have peace about my decision and am excited for the future.  I am also relieved to not have to worry about my future employment for a long time. 
As far as this blog, I hope to continue to blog whenever I find topics that I think will be of interest, and/or topics that I need to make sure I remember for later.

Friday, March 25, 2016

A Java Agent Which Extracts a File Attachment to the D:\ Drive of the Server

Recently I was given an assignment to extract a file from a Notes document and place it on the server’s D:\ drive.  The file would then be picked up and delivered elsewhere.
I was originally asked to place this file in a network share but I knew that Notes security only allows access to the file system of the server itself.  I decided to create a scheduled java agent to perform the extract because I just couldn’t bring myself to create something new in Lotusscript.

Background

Each document only contains a single attachment so I didn’t have to worry about multiple attachments.  The code would have to be modified to accommodate that use case.  The attachment directory also needed to be kept in a keyword document in case the location is moved at a later point in time.

Functionality

The code also is robust enough to write a status back to the database whether the extract was successful or not.  The database contains a view has a column that reports back the result.
The agent first checks whether the file is already there, and then fails if it is. Obviously it is impossible for one to have two files of the same name in the same directory.  The agent then performs the extract and then verifies that the file is now in the directory. 

The Code

The code here is self explanatory so I am don't think there is a need to do a code explanation. The comments tell what is happening.

import java.io.File; 
import java.util.Enumeration; 
import java.util.Vector; 

import lotus.domino.*; 

public class JavaAgent extends AgentBase { 

    public void NotesMain() { 

      try { 
          Session session = getSession(); 
          AgentContext agentContext = session.getAgentContext(); 
          
          Database db = session.getCurrentDatabase(); 
          
          //Get Keyword containing attachment location 
          String searchKWString = "SELECT Form = 'frmKeyword' & Keyword = 'AttachmentDirectory'"; 
          DocumentCollection locationCol = db.search(searchKWString); 
          Document locationDoc = locationCol.getFirstDocument(); 
          String location = locationDoc.getItemValueString("Choices"); 
                    
          //Get all Unprocessed Documents 
          String searchString = "SELECT Form = 'Document' & VCC_Upload != 'Y'"; 
          DocumentCollection unprocessedCol = db.search(searchString); 
          Document doc = unprocessedCol.getFirstDocument(); 
          Document tempDoc = null; 
                    
          while(doc != null){ 
                  //Extract attachment to location on server. Documents only have one attachment. 
                                    
                  Item item = null; 
                  Vector attachmentNames = new Vector(); 
                  Enumeration itemEnum = doc.getItems().elements(); 
                  while (itemEnum.hasMoreElements()){ 
                          item = (Item) itemEnum.nextElement(); 
                      if (item.getType() == Item.ATTACHMENT) { 
                            attachmentNames.add(item.getValueString()); 
                        } 
                  } 
                  String attachmentName = (String) attachmentNames.firstElement();                 
                  EmbeddedObject eo = doc.getAttachment(attachmentName); 
                  
                  if(eo != null){ 
                          //Check if File already present in folder 
                          File file = new File(location + eo.getName()); 
                          boolean existsBefore = file.exists(); 
                          boolean existsAfter = false; 
                          
                          if(!existsBefore){ 
                                  //Perform Extract               
                              eo.extractFile(location + eo.getName()); 
                              existsAfter = file.exists(); 
                                                            
                              //Mark document as processed 
                          if(existsAfter){ 
                          doc.appendItemValue("VCC_Upload", "Y"); 
                          doc.appendItemValue("Upload_Time", new java.util.Date().toString()); 
                          doc.appendItemValue("UploadMessage", "Upload Successful"); 
                          doc.save(); 
                              } 
  
                          } else { 
                          //Mark document as unsuccessful 
                                  doc.appendItemValue("VCC_Upload", "Y"); //prevents document from being considered in future runnings 
                      doc.appendItemValue("Failure_Time", new java.util.Date().toString()); 
                      doc.appendItemValue("UploadMessage", "Extract Failed Due to file being extracted previously"); 
                      doc.save();   
                          } 

                          if(!existsBefore && !existsAfter){ 
                         //Mark document as unsuccessful 
                      doc.appendItemValue("VCC_Upload", "N"); 
                      doc.appendItemValue("Failure_Time", new java.util.Date().toString()); 
                      doc.appendItemValue("UploadMessage", "Extract Failed"); 
                      doc.save();             
                          } 
                  }     
              
                //Get next unprocessed document 
              tempDoc = unprocessedCol.getNextDocument(doc); 
              doc.recycle(); 
              doc = tempDoc; 
          } 
          
      } catch(Exception e) { 
          e.printStackTrace(); 
       } 
   } 
} 

Conclusion

I realize that this is a limited use case, and is certainly nothing cutting edge, but hopefully this is of use to someone or future me when they need it.  A big hat tip to Jesse Gallagher who pointed me in the right direction.

Saturday, February 6, 2016

Thoughts on IBM Connect 2016

Three days have passed since I returned home from IBM Connect in Orlando. This was my fourth ‘Sphere’ with my last being two years ago. This is my first time to attend as an IBM Champion! My overall impression was extremely positive. It certainly exceeded my expectations, and my expectations were pretty high.


My Goals for a Successful Conference


My personal goals were split into three equal parts:
  1. Spend time with existing friends/acquaintances as part of the finest software community in the world 
  2. Network, network, network which overlaps with #1 
  3. Increase my knowledge by attending technical sessions
Community
The community was out in force this year with just a few notable exceptions. The community we have really is something special, amazing really. I am tempted to list all the names of people I enjoyed seeing but don’t want to miss anyone. It was great to meet some people that I knew of but never met such as John Dalsgaard, Simon Peek, Greg Reeder, and Jeff Twardowski.

I also really enjoyed spending time with my Navy Federal coworkers Ernie Javier and Blair Armeau. Prior to this, I had only known Blair via sametime so it was great to meet in person. To me now, they are friends, not just coworkers.


When it was time to leave immediately after the closing session, I was tired and ready to see my family, but still it felt hard to leave such a group of amazing people.


I would be remiss if I didn’t mention the people whose presence was missed. It would have been better with Marky Roden, David Leedy, Mike McGarel, Peter Presnell, Ulrich Krause, and Shean McManus.
Networking
Connect 2016 was also very productive for me on the networking front. At my current employer they don’t have any more XPages projects in the works so I have to decide whether to stay or go. This conference really gave me clarity for the future. I don’t know how things will play out, but I had some conversations that were very encouraging. Along those lines, if anyone reading this is looking for a developer with 20 years of total experience and 3.5 years of XPages then please reach out to me at zavocki@hotmail.com.
Sessions
The quality of sessions this year was definitely on par with past conferences. The topic that really surprised me this year was Bluemix. Although I had seen sessions on it before, the progress that the team has made was very impressive. It has definitely caught my attention.

These were my favorite sessions:

  1. The XPages of Things: Integrate Bluemix into your XPages Applications for a World of Possibilities. I think that John Jardin blew everyone away with what he demonstrated in this session. For me, the relevance of BlueMix went way up with this session.
  2. Get Hands-On with XPages Apps for Bluemix – Martin Donnelly and Brian Gleason gave more details on what Bluemix with plenty of demos. Because I previously had been inspired by John, this session has more meaning for me.
  3. The Grid, the Brad, and the Ugly: Using Grids to Improve Your Applications – This session by super champions Brad Balassaitis and Paul Calhoun was very informative and the audience was extremely engaged. Even though I had a fair amount of experience with the topic I certainly learn quite a bit.
  4. Real-time Video Chat XPage Application using Websocket and WebTRC Technologies – first time attendee and hopefully future champion Csaba Kiss showed two methods of having a real time chat application inside of XPages. The material was comprehensive and he covered a lot, and certainly inspired the developer audience to think of ways to integrate this into new and existing applications.
  5. Once You Go Graph… Nathan Freeman is obviously extremely passionate and knowledgeable on this topic. I had been wanting to see this session at MWLUG, but it was presented opposite of the one I was giving. I first heard of graph databases two years ago, the first and only time I met the late great Tim Tripcony. He was just as passionate on Graph database and spent a half hour explaining them to me. I like sessions that inspire you to want to learn more on your own.


General Impressions

OGS

For the most part, I really liked the OGS, compared to past years it seems to take itself less seriously.

I was very unimpressed with the guest speaker Jason Silva. I thought his message was intellectual cotton candy, and visually distracting. I was very impressed with the case study from West Africa on how an XPages application has helped improve fair trading between farmers and the middlemen who deliver the product to market. 

The drama where they showed the new products being used was funny and well done. It was obviously contrived and very staged, but that is to be expected with this type of demo. I thought the break in the middle was a good idea.

Universal Studios

Whenever I go on rides at parks like Universal, I get reminded that I am not a kid anymore. Even though I got queasy, I  enjoyed spending time with John Jardin, Andre Horak, and Paul Withers on the Harry Potter ride. The castle there is extremely impressive as were the animated paintings. After that John convinced me to ride the dragon coaster. It might have been the fastest coaster I ever went on. I would have liked to ride it again but the stomach would not allow. 

The Venue

I had no problem with the venue. I hope that they continue it there next year, although nothing was announced. I like the fact that I could stay nearby at the Days Inn which was only a five minute walk. This year I am paying my own way to be at the conference so having reasonably priced hotel and food options nearby is a huge plus. When we were on Disney property, we had none of that. News like this doesn’t make we want to spend money on the mouse, even if they backtracked later due to public pressure. 

An Apology

I feel the need to apologize for my awful cough which I am sure was annoying to those sitting around me. I know that I was a distraction and I appreciate that everyone seemed to be understanding.

Final Thoughts


Overall, I felt a very positive vibe from those around me. It was encouraging to see many first time attendees, as well as some very engaged younger developers. The conference is alive and well, and I hope IBM does nothing radical to change that next year.

It was an big honor to have my photo on the big screen before the OGS