Sunday, May 31, 2020

PGP encryption/decryption using Apache Camel, Spring Boot

First, an update on the computing environment. The Acer C720 i3 core with 4G RAM Chromebook was updated with a 128 GB SSD hard drive and converted to Ubuntu 18.04, most recently to Lubuntu 20.04. It's working great using the xcfe desktop I was used to using with Crouton.

So, I've got a requirement to convert a bunch of files downloaded from an SFTP server encrypted with PGP. There's plenty of resources online to see how to do generate a public-private key pair. Export the public key to an *.asc file, and make a copy of the private key, also in *.asc. These will both by armored, meaning Base64 encoded.

Copy the keys to the project root of your Spring Boot application, e.g. in a /keys directory.

From the documentation at PGP - Apache Camel, add the following dependency to build.gradle,

compile group: 'org.apache.camel.springboot', name: 'camel-crypto-starter', version:camelCoreVersion 

Now, we're ready to add some code. I've uploaded the code to a GitHub gist.

Create folders for /pgp/original, /pgp/encrypted, and
/pgp/decrypted. Create a file in /pgp/original with some secret text. Run PGPEncryptor, and you should see output in the encrypted and decrypted folders with your encrypted file, and decrypted file respectively.

Well, it's Sunday and this POC needed to be complete for Monday, just in time!

Much help was obtained from this blog post and other resources found around the web. Many thanks to the authors!

Tuesday, November 10, 2015

Why Computer Programmers Should Stop Calling Themselves Engineers - The Atlantic

There are lots of analogies to be made between the construction trade and software development. Maybe a follow up piece? It's only natural to call the practitioners by engineering titles. Not everyone who codes is an engineer, just as not everyone who writes is a journalist. However, a lot of the same concepts go into each. The interesting part is how far the analogy holds, not probing at the weak points, but it would take a practitioner to appreciate it. I probobly wouldn't click on a story about blogging versus journalism. Why is a journalist writing about engineering? It seems the journalist in this case is making the same mistake he decries, or pehaps he's qualified. 



Professional licensing is almost singularly the only difference between the professions. It's called Software Engineering for a reason, with the emphasis on "soft", versus "hard", each with its own set of requirements. Not recognizing this difference only emphasizes the authors lack of subject matter expertise. Besides, there are volatile components, mainly memory that can inexplicably fail, causing a car to not start due to software failing to error check. That's a cost component, and we know how that works out in the manufacturing industry. The similarities across disciplines are more numerous and far more interesting than the differences.



Why Computer Programmers Should Stop Calling Themselves Engineers - The Atlantic:



'via Blog this'

Saturday, March 28, 2015

Spring 3 MVC and REST

For anyone working with Spring 3 MVC and REST, I spent a lot of time getting this sorted, so I thought I would post some results.

Spring 3 is a few years old now, but I'm using it at my day job, so that's what I'm using here. You can get a Spring 3 MVC project running by following any number of tutorials. I won't go into those details here.

The biggest gotcha I ran into wasn't well documented anywhere, in fact, I found two singular pieces of information which enabled me to get this code working after some considerable effort. First is using Jackson version 1.9, instead of 2.x, for Spring MVC versions prior to 3.1. Here's the POM entries.

<properties>
 <jackson.version>1.9.13</jackson.version>
</properties>

<dependency>
 <groupId>org.codehaus.jackson</groupId>
 <artifactId>jackson-core-asl</artifactId>
 <version>${jackson.version}</version>
</dependency>

<dependency>
 <groupId>org.codehaus.jackson</groupId>
 <artifactId>jackson-mapper-asl</artifactId>
 <version>${jackson.version}</version>
</dependency>

Secondly, with Spring MVC 3.0, you need this in your bean configuration;

 <!-- JSON support -->
 <bean id="jacksonMessageConverter"
  class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"></bean>
 <bean
  class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
  <property name="messageConverters">
   <list>
    <ref bean="jacksonMessageConverter" />
   </list>
  </property>
 </bean>

So, let's take a request from the beginning. I used Advanced Rest Client chrome extension, but this works as a simple URL request. Your web.xml file needs handle the request,

<!-- Initialise the Spring MVC DispatcherServlet -->
<servlet>
 <servlet-name>spring-myapp</servlet-name>
 <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
 <load-on-startup>1</load-on-startup>
</servlet>

<!-- Map the Spring MVC DispatcherServlet to intercept *.sp requests -->
<servlet-mapping>
 <servlet-name>spring-myapp</servlet-name>
 <url-pattern>*.sp</url-pattern>
</servlet-mapping> 

<servlet-mapping>
 <servlet-name>spring-myapp</servlet-name>
 <url-pattern>json/*</url-pattern>
</servlet-mapping> 


Spring maps the URL to a controller,

<context:component-scan base-package="com.nml.myapp.web.controller" />
<context:annotation-config />
<mvc:annotation-driven />

and with Jackson in the classpath, the controller code returns the JSON response,


@Controller
public class JsonController {

 private static final Logger logger = Logger.getLogger(JsonController.class);

 @RequestMapping(value = "/getCategories", method = RequestMethod.GET)
 public @ResponseBody List<String> query() {

  logger.info("rest request: getCategories");
  
  List<String> list = new ArrayList<String>();
  list.add("object is list");
  list.add("second object"); 
//  model.addAttribute("list", list);
  
  return list;
 }
}

Here's the result. My first good night's sleep in a week.


Chromebook and Crouton Goodness

I've purchased a new Chromebook, an Asus C300 EDU with a 13" screen, 4G RAM, 32G SSD, an Intel N2830 dual core processor. It's quite an improvement over the Samsung 303C that I've used for a couple of years, in fact, we have one for every member of the family. It's just easier that way!

One of the reasons I went with the Chromebook was the ease of use. Everything works with a Google Account, and it integrates well with Android. I use Google Docs extensively, so there's no need for lot's of disk space.

I got this particular model with an Intel processor for two reasons. 4G RAM is a necessity for intensive applications, and I use Crouton which installs Ubuntu Linux side by side with ChromeOS, which runs on a scaled down version of Linux. Some Linux applications depend on native compiled libraries which aren't available for ARM based processors, like the Samsung chromebooks and Raspberry Pi.

I've been using some Amateur Radio applications just fine on the ARM processor, but Eclipse wouldn't run, and I blogged earlier about hp printing, although cloud printing works fine.

So, now I've got this great Chromebook with plenty of memory, runs all my linux apps, and I've got it connected to an older Dell 24" external monitor, keyboard, and mouse. Life is good, praise the Lord! Amen and amen!

Sunday, May 18, 2014

CHIRP and Ubuntu 12.4

Why not? I've got a Chromebook running Linux, a programming cable for the Baofeng UV-B5 HT, and all I needed was the program, which just happens to be open source software recommended on Linux.

After installing from apt-get, the version was so old, what was the point of ever putting it there. Maybe more recent repos have newer versions. Anyway, d/l'd the latest tar, extracted it and ran it, although I was getting an error,

"could not open port /dev/ttyUSB0: [Errno 13] Permission denied:"

and the documentation I could find was either run the program as root [wrong], or add the user to the dialup group. This was partially right, the correct group was the serial group, and all is well.

Now I have a Baofeng programmed with all the repeaters in the area, around 62 of them. The CHIRP program allows imports and exports from CSV files, and downloads and uploads to and from the radio. I may have used CHIRP previously on Windows on a P25 GRE scanner I used to own, but it's always nice not to use Window$.

Sunday, May 11, 2014

HPLIP printing module, foo2zjp, and Google Cloud Print (HP p1102w)

My family has gone over mostly to Google, with Google Accounts for everyone, Chromebooks and Nexus devices. I say mostly because I still have my work computer and an old laptop which still run MS Windows.

The biggest drawback thus far has been a lack of printing support. Last year, we purchased an HP p1102w wireless b/w laserjet printer for around $100. Setup was relatively painless on Windows, but I messed around longer than I wanted to getting it to work with Google Cloud Print, with limited success. Thus, our printing options were limited to saving work in Google Docs and printing them from a Windows PC. That all changed yesterday!

In the process of setting up my Chromebook with Ubuntu 12.4.04, upgrade to a newer version coming soon, I decided to attempt printing to the wireless printer. The Samsung Chromebook I'm using has an ARM processor as do most Nexus devices. This causes some binary packages built for Intel to fail badly, most notably, Minecraft and Skype, from what I've read. This limitation bit me yesterday when I installed HPLIP, HP's open source Linux printing support, and my printer requires a proprietary plugin from HP, which is only available in binary form and has not been ported to the ARM processor. Major league fail!

Fortunately, there is an alternative driver for HP printers, foo2zjp. After uninstalling HPLIP, I installed foo2zjp and was finally able to print to the HP p1102w wirelessly. Haven't tried printing over USB, except using HPLIP, which failed, since I haven't needed to do so. I documented all of this on the Crouton Wiki as an alternative driver for HP printers, for printers requiring the proprietary HP plugin, and distros running on ARM, so perhaps a somewhat limited audience. I also posted my results on the Raspberry Pi user forum and voted, subscribed and commented on the bug report for HPLIP. Then I contributed via PayPal to the development effort for foo2jzp. After all, these guys are doing the heavy lifting.

In the process of doing all of this, I upgrading the firmware for the printer, and completed setup of Google Cloud Print, so I've realized my goal of a printing solution for the family, and we're able to print from the Google Chromebook, Nexus tablets, and smartphones to the laserjet printer. Not a bad day!

Next up will be installing the latest version of Ubuntu on the Chromebook using Crouton. I'm blogging this from the Ubuntu installation, and very few exceptions, could ditch Windows for this form factor and user interface.

That's enough for one day, Happy Mother's Day!

Friday, March 28, 2014

Ham Radio - Installing Ubuntu on Chromebook using Crouton

I'm sitting for my General ham radio license next month and I've been thinking through how to get online in digital HF modes. This led me to install Ubuntu on a Samsung Chromebook using Crouton. I've documented the steps I've taken to install Ubuntu and some software packages for digital HF operation.

I'm setting up a ham shack as a portable go box for ARES and field work, including camping. Everything will run off an external power supply. There's a lot to learn and do.

Currently, I have a Kenwood TM-281A on 2m, and a Baofeng UV-B5 HT dual band. Ubuntu will be the front end of a digital HF station with a Signalink USB interface to an HF radio/antenna.

Monday, March 22, 2010

Sunday, February 28, 2010

Google Checkout is here! Added a custom shopping cart using the Google Checkout XML API. A slight wrinkle getting JDOM to work with GAE, but a quick fix searching JDOM and "Google App Engine", on Google, of course, and everything is running nicely.

Looking into monetizing the site, but don't won't to overburden the download pulling in a lot of embedded content.

Synchronizing the product database now, and should begin seeing some hits. Oh, didn't mention, integrated the site with Google Analytics. Should have done it before hitting the forums, but no bites, yet, on product integration, either. Seems everyone has been there, done that.

But, not on Google App Engine, cheers!

Wednesday, February 24, 2010

Product Advertising API

Thinking about adding Amazon Advertising to app engine

Product Advertising API

Sunday, January 31, 2010

Working with GWT, beginning with the Getting Started tutorial, trying to deploy Bookstore to GAE in one weeked! Almost got stumped adding ClickHander to a Grid, thankfully someone posted this solution,

// listen for mouse events on the results grid
resultsGrid.addClickHandler(new ClickHandler() {
   public void onClick(ClickEvent event) {
      final HTMLTable table = (HTMLTable) event.getSource();
      final HTMLTable.Cell cell = table.getCellForEvent(event);
      // cell.getCellIndex() COL
      // cell.getRowIndex() ROW
   });

Very cool!

Sunday, April 19, 2009

Alternating row colors using Struts2
<s:iterator value="results" status="status">
<s:if test="#status.odd">
<tr bgcolor="#F8ECE0">
</s:if>
<s:else>
<tr>
</s:else>

Saturday, February 21, 2009

Struts2 nested checkbox tag inside iterator

Using the s:iterator tag and status attribute it's possible to display and update values of complex types within a collection.

For example, using an iterator tag,

<s:iterator value="results" status="status">

<s:hidden value="%{product.sku}" name="results[%{#status.index}].product.sku" />

<input type="checkbox" name="results[<s:property value="%{#status.index}" />].selected" <s:property value="%{selected}" />>

</s:iterator>

within a form tag, the submit action will update the list of results in the Action class, where my action class has

protected List<ProductBean> results;

with getters and setters, and my ProductBean has,

private Product product;

with getters and setters, and

private boolean selected;

/**
* @return the selected
*/
public String isSelected() {
    return selected ? "checked" : "";
}

/**
* @param selected the selected to set
*/
public void setSelected(String selected) {
    this.selected = selected == null || selected.equals("") ? false : true;
}

Note: If you find something useful, please leave a comment, thanks!

Wednesday, July 23, 2008

Implement connection pooling in Tomcat 5.5 using Hibernate 3, MySQL 5
Culled from various sources:

Add JDBC driver, mysql-connector-java-5.1.5.jar to apache-tomcat-5.5.xx\common\lib

Add resource-ref to WEB-INF/web.xml
<web-app ...>

...

<resource-ref>
    <description>
        Resource reference to a factory for java.sql.Connection
        instances that may be used for talking to a particular
        database that is configured in the server.xml file.
    </description>
    <res-ref-name>jdbc/MySqlDb</res-ref-name>
    <res-type>javax.sql.DataSource</res-type>
    <res-auth>Container</res-auth>
</resource-ref>

</web-app>
Add session-factory name attribute and property elements to WEB-INF/classes/hibernate.cfg.xml
<hibernate-configuration>
    <session-factory name="java:hibernate/SessionFactory">

        <!-- JNDI Connection -->
        <property name="hibernate.connection.datasource">
            java:comp/env/jdbc/MySqlDS
        </property>

        <property name="hibernate.dialect">
            org.hibernate.dialect.MySQLDialect
        </property>

...

    </session-factory>
</hibernate-configuration>
Add Resource to META-INF/context.xml, alternatively add Resource to GlobalResources in tomcat server.xml
<?xml version="1.0" encoding="UTF-8"?>

<Context path="/MyApp" reloadable="true">

  <Resource name="jdbc/MySqlDS" auth="Container"
    type="javax.sql.DataSource"
    maxActive="100" maxIdle="10" maxWait="10000"
    username="myUsername" password="myPassword"
    driverClassName="com.mysql.jdbc.Driver"
    url="jdbc:mysql://localhost:3306/bookstore?autoReconnect=true"/>

</Context>
That should work!

Sunday, June 08, 2008

Struts2 checkboxlist UI tag rendering one item per line
After struggling with this UI tag for a some time today, I gave up and was attempting to use s:checkbox inside of an s:iterator to render one item per line, unsuccessfully.

So, upon revisiting s:checkboxlist, I found that it's a relatively painless thing to override the checkboxlist.ftl file described here, http://struts.apache.org/2.0.9/docs/template-loading.html, add a break at the end of this line

<label for="${parameters.name?html}-${itemCount}" class="checkboxLabel">${itemValue?html}</label><br />
and save the file in the webapp/template/simple dir of my web application.

Friday, June 06, 2008


Hello, all!

I've maintained a blog for several years on my own server, and decided it was time to move to a lower maintenance solution. Spaces looked like a good choice, so here goes!

Most of my posts will be technically oriented, simply because there's never enough good information when looking for a solution to a tough problem. Blogging serves as documentation for myself, as much as it does for anyone else trying to solve the same or similar problems.

I have experience using Java, CSS, HTML, JavaScript, Struts 2, Maven 2, Hibernate 3 and other Open Source and Internet technologies. Please feel free to contact me with any questions or comments.

Wednesday, September 24, 2003

Welcome to Laney Consulting Web Log, enjoy your visit!