safe computing – weak case for weakening encryption

You cannot strengthen the weak by weakening the strong.

William J. H. Boetcker

This quote has been often misattributed to Abraham Lincoln.  This is actually a very relevant thought with the respect to economics.  Indeed you cannot improve everybody’s lot in life by taking from the economically strong no matter how well intentioned your goals are.

I think that this particular quote is even more meaningful with respect to improving privacy and encryption.

Some of the forward thinking political types think that in the very near future all communications will be using encryption.  They also believe that this will destroy the ability of governments to gather intelligence of evil doings.  The “Five Eyes” are at the minimum hoping that silicon valley can find a way that will support the interests of privacy and security.

The desire of these countries sounds very positive but to some ears that sounds like creating a solution that will allows the “protectors” to read encrypted solutions in situations when it is “important”.  This last sentence when properly parsed will actually mean that some backdoor will exist to allow the governments of the world (and any really clever hackers) access to your communications.

That wouldn’t be so bad except the history of man is full of situations where people abuse their positions of power.  Who wants to send out private communications knowing that some government wonk, perhaps your ex-husband, could access your messages with the universal iPhone decryption key.

That would be worrying enough but the world is filled with malicious players.  People interested in looking at more than little text messages you sent to someone special.  They would be taking advantage of weaker communication standards to eavesdrop on our financial transactions.

Weak encryption solves problems. Right?

Every time I read about governments wanting weaker encryption I think back to a specific Dilbert cartoon.  The pointy haired boss is explaining about earnings reports and how they need to be smooth for lazy analysts – the same is true for encryption.  No encryption or easily breakable encryption makes it a lot easier for security agencies to examine messages.  Yet does this really catch more plots?

Weaker standard encryption doesn’t mean that attacks will then be caught before they take place.  People can only be caught doing bad things if they are in constant communication about their plans, someone is listening in and important details are being shared.  Wouldn’t this have helped for some of the terrible incidents that have occurred in the past such as 9/11, London bombings, or Madrid bombings?

Having no encryption at all might not have made any difference at all, assuming that any encryption was used for those incidents.  In the spy novels, action adventure books and other thrillers the bad guys don’t coordinate these things long distance.  Sure, the big boss might know that a special unit has a given mission at a certain location but that is usually it. There is no communication.

Terrorist groups, well the really successful ones, appear to plan an attack and then let that unit deal with the details of the attack.  They don’t appear to be remotely controlled by their organizers.

Recent digital access is an anomaly

It is only the last twenty or so years that the masses have been sending emails and cat pictures through the ether to a recipient.

In the distant past it was possible to listen in on the telegraphs that were being transmitted.  In the recent past it was possible to have phone conversations, and it was also possible that they could also be listened in on.  However, for most of the last 100 years it has not been possible to have a permanent exact replica of every message sent or received so that they can be replayed and stored for future use.

This relatively recent access has been most undoubtedly incredibly helpful for the security services and it is understandable why they are addicted but this is not the normal state over the last century.  The ability to retroactively look through a previously encrypted phone is probably more desirable for prosecution in a case after the fact to help prove intent.

Even if all phones were unencrypted, the issue of bad people using prepaid phones would make the argument moot.  Clever criminals and terrorists would use these phones for very small transmissions of reasonably innocuous messages.

A case of Hubris

It is pure hubris to believe that only the existing security services of the large countries are capable of creating a method or cipher that cannot be broken.

Do the security services really believe that if they weaken the encryption solutions that they are the only ones who can come up secure solution?  Of course not every code slinger can create a flawlessly secure solution but there a lot of different types of other known solutions that can easily be used.

substitution cipher

public key cryptography

one time pad

Steganography

It would obviously be much easier for less talented criminals or terrorists if their Apple phone or Android phone had built in end to end encryption but any of these other methods could be used to keep secrets.

These methods are all known by the authorities so they would only keep secrets for a certain period of time but depending on the situation the secrets might only need to be kept long enough to do bad things.

Cryptography is not a secret

The internet is full of information about encryption but it isn’t even necessary to go to those lengths.  You can purchase books from Amazon about encryption.  I started to count the but there were so many books to choose from.  They all looked pretty good to me.

Besides, people are creative when trying to find a method of keeping secrets.  Good methods can be developed by prisoners much to the chagrin of their keepers.

 

Oh, here is the original quote in context.

You cannot bring about prosperity by discouraging thrift. You cannot help small men by tearing down big men. You cannot strengthen the weak by weakening the strong. You cannot lift the wage-earner by pulling down the wage-payer. You cannot help the poor man by destroying the rich. You cannot keep out of trouble by spending

William J. H. Boetcker

 

Posted in Soapbox | Tagged , , | Leave a comment

just making it – revisiting my cube

Some time back, I had a fair amount lot of free time.  I spent the time working with a friend Mikhail in the evenings to create my own LED cube from scratch.  It was actually quite a bit of fun, the electronics was not overly complicated with most of it being done by a Raspberry Pi. It was fun to see both the hardware and the software side by side.

raspberry pi powered cube

The problem with that particular cube was using the Raspberry pi.  The Raspberry pi is a great platform but it is a computer and it needs time to start up the operating system and more importantly it needs to be shutdown in an organized manner.

The Raspberry pi is an awesome little computer but the startup and shutdown times are my main problem.  I only have a few hundred lines of code that needs to be run so I don’t need a four core 1.2 gHz computer, only need a few megaherz.

Arduino to the rescue

The first release of the Raspberry pi was in 2008 at 900 mHz for 35 dollars was truly amazing but it wasn’t the first of this type of hardware for do-it-yourself electronic projects.

I actually was never involved in the DIY electronics when the Arduino came out but I think that the Arduino was pretty much the pioneer of this space.  The Arduino was not only hardware but it was open source hardware.  The fact that it was open source helped it to expand and multiply into the number of models that we see today.  Well, being open sourced helped but also due to the release of ever increasing sophisticated processors from ATMEL which powered these Arduinos.

Today it is possible to get what is essentially little computer that is not much larger than a couple of postage stamps.

This “advanced” processor is running 20 MHz and contains 32 KB of program memory. Not quite the latest gaming personal computer but it is similar to the original Apple ][ personal computer, but it is more than enough to pass the commands to the cube to switch leds on and off using the I2C protocol.

New Hardware

The Raspberry Pi supports I2C but the Atmega328 does as well.  The I2C protocol is just a matter of two lines – a data line and a clock line.  As far as the hardware was concerned, all I needed to do was to connect the data, clock, power and ground to the Arduino atmega328.

On the software side, I was pleasantly surprised at actually how easy it was using the Arduino libraries to do I2C and to convert my code over.

Sure, I did have to make a number of small changes but the process was pretty painless.  Replace my printf statements with Serial.println statements but the main changes were connected with the I2C protocol.

The libraries to do this were part of the standard development environment.  The class that you need to use is the Wire class.

Old Code

   bcm2835_i2c_setSlaveAddress(cathode);
   char cmd2[] = { IODIRA, 0x00, 0x00 };
   check_retcode(bcm2835_i2c_write(cmd2,sizeof(cmd2)));

New code

   char cmd2[] = { IODIRA, 0x00, 0x00 };
   pi_i2c_write_command(cathode, cmd2, sizeof(cmd2));

The pi_i2c_write_command is my own method but it simply does call the three methods (beginTransmission, write, endTransMision) that are required in order to send an I2C command.  Only five lines of the twenty six are required, the rest were used for monitoring the program while it was being ported.

void pi_i2c_write_command(int device_address, char cmd[], char len)
{
  int idx = 0;
  if (debug != 0)
  {
    Serial.println("begin pi_i2c_write_command\n");
    Serial.print("address ");
    Serial.println(device_address, HEX);
    Serial.print("arguments ");
    Serial.println(len, DEC);
    for (idx = 0; idx < len; idx++)
    {
      Serial.print(cmd[idx], DEC);
      Serial.print(" ");
    }
    Serial.println("\n");
  }

  Wire.beginTransmission(device_address);
  for (idx = 0; idx < len; idx++)
    Wire.write(cmd[idx]);
  Wire.endTransmission();

  if (debug != 0)
    Serial.println("end pi_i2c_write_command\n");
}

arduino powered cube

 The Problems

I did have one small problem while porting my software that was really an oversight. Before you try and transmit any data via the I2C bus you need to initialize it first with the a call to “begin”.

Wire.begin();

If you don’t make this call, none of the subsequent calls do anything.  In my haste, I did have this line but it was in the wrong spot in my initialization code.

My code does have comments but it has been a while since I was using the 23017 16 bit I/O expander.  So I did have a few questions how it worked exactly.

While doing my debugging I did read up more about the chip and I do have a few clarifications that describe the code’s behavior.

register Description
IOCON This register is used to set various configuration options on the chip. The two most interesting as far as this program goes is the BANK (bit 7) and the SEQOP option (bit 5).

The BANK bit changes the addresses of the various registers.  When BANK=1 then the address for IODIRB is 0x01 but when the BANK=0 then the address for IODIRB is 0x10.

The order of the registers is more interesting in conjunction with the SEQOP register.  The SEQOP=1 allows the chip to write multiple bytes sequentially.  When the BANK=0 then the register pairs are next to each other.

IODIRA

IODIRB

These registers are used to set the direction of the I/O. The IODIRA register controls the direction for first 8bit port (PORTA) and the IODIRB register controls the direction forthe second 8bit pot (PORTB).
OLATA

OLATB

These registers are used to set or clear the latches for the two ports.

The other important detail is that the current flows to the various LED’s (via the I/O expander) when the anode (layer) is set to on and the cathode (column) is set to off.  This sounds exactly what you would expect for lighting up a LED, power goes to anode and ground goes to cathode.

Posted in programming, ready to publish | Leave a comment

interrogating your code – dipping your toes into java’s reflection

Perhaps the coolest programming language ability that I was never allowed to use was reflection in Java. Why? Well, thats another story.

What exactly is reflection? Well, reflection is a set of low level methods that can be used to inspect code while the program that is doing the inspecting is running.

This puts the program in a very unique situation where it can interrogate objects that it is working with. Thus the program can then make decisions based on what information it finds on the class that it is inspecting.

This makes it possible to inspect an object to see if it contains a certain method. This allows your program to make the decision which method to use if multiple valid methods exist. One, perhaps somewhat contrived, example of this would be that your program could check and see if the new 2.0 version of your method existed.

Method method = null;
try {
    method = financialCalcObj.getClass().getMethod("calcBreakEvenV2", null);
}
catch (Exceptione ex)
{
    // not really an error, use standard method
}
try {
    if (method == null)
        method = financialCalcObj.getClass().getMethod("calcBreakEvenV1", null);
}
catch (Exceptione ex)
{
    // wow, thats bad
    System.exit(1);
}
method.invoke(financialCalcObj, null);

If this doesn’t seem pretty amazing just remember that you cannot do the following unless you already have all methods defined at compile time.  (which does defeat the idea of trying to future proof your code)

try {
    financialCalcObj.calcBreakEvenV2();
}
catch (Exception ex)
{
    financialCalcObj.calcBreakEvenV1();
}

The difference between the two sets of code is that in the reflection example was compiled before version 2 of this method existed.  We just knew that it would show up eventually.  This could be extended to either use the highest version that existed or to use the version of a method based on a command line argument.

No magic just a bit of forethought required

A program that uses reflection in this manner might not make much of a difference if the same set of class files or jar files are used each time.  It does allow some flexibility but if the code base never really changes it is not necessary to go to these extremes just to change how the program behaves at runtime.

The program that I had been envisioning  was going to use this technology to dynamically support multiple language text.  The dynamic part was the program would convert numbers into text of the desired language.  The program would run every few minutes so it would be possible to exchange jar files between runs, however I think there is an even better solution.

ie.

    numberToTextGerman
    numberToTextEnglish
    numberToTextFrench

Instead of continuously replacing the language jar – each time with more languages I would take a slightly different route.  I would structure the program in such a way that each new language with its methods would exist in its own jar file.

The actual program itself would retrieve the data which needs to be processed and this would include the form language.  Most of the form text might be read from a database table or a possibly a file but the conversion between numbers and their textual descriptions would need to be some sort of program.

Because each language would exist in its own jar file and because the program would be receiving the target language in the input data, it would be possible to support new target languages whenever they were ready.

Simply copy the new jar file to the program directory and change the list of supported languages in the application.  The program would do the rest.  Well, the script or batch file that calls the program does need to ensure that it will include the new jar file.

I simply create the classpath from the list of jar files available and the script which runs the program would be called periodically from the crontab or other scheduler.  So the simple act of adding the jar file to the programs library directory automatically adds support to the program for this new language each time the script is run.

Reflection classes and methods

The Java API has the Method class which can be used to retrieve and inspect methods.  It is possible to query the name, which parameters types it expects, the return type and of course the ability to call the method.

class Method

  • String getName()
    Returns the name of the method.
  • Class[] getParameterTypes()
    Returns an array of Class objects which represent the parameters, in the order of declaration.
  • Class getReturnType()
    Returns a Class object that represents the return type of the method.
  • Object invoke(Object obj, Object... args)
    Invokes the underlying method represented by this Method object with the specified parameters.

class Field

The Method class allows you to interrogate a method to see exactly what parameters it is expecting and so forth but it is also possible to perform similar queries but on the class level for defined variables.

Once you have retrieved your variable from the class it is it can be used to then query information about the fields.  It is possible to retrieve the name, the type or even the value.

  • String getName()
    Returns the name of the field.
  • Class getType()
    Returns the type of the variable.
  • Object get(Object obj)
    Returns a Class object that represents the return type of the method.

 

Multilingual support example

For this example, it is expected that every language support class must have a certain core set of methods.  The easiest way to ensure that this happens is to create an interface of those methods.

To demonstrate this rather interesting idea using reflection, I am not going to have complete language functionality just enough to demonstrate how it works.  The language classes will each have to support two numberToText methods.

package com.acmesoft.support;

public interface languageInterface {

	public String numberToText(long value);
	public String numberToText(double value);
}

The actual reflection magic happens in the Numbers class. This class essentially is a small dispatcher by looking up the method based on the language that is passed in.

package com.acmesoft.support;

import java.lang.reflect.Method;

public class Numbers 
{
	public static String number2TextClass = "Numbers";
	public static String number2TextMethod = "numberToText";

	public String numberToText(String language, Integer val) throws Exception 
	{
		String outputtext = "";
		
		try{
			String searchObject = "com.acmesoft.support." + language ;
			Class cls = Class.forName(searchObject);
			Object obj = cls.newInstance();
			Method method = null;

			/* for methods with other parameters 
			//no paramater
			Class noparams[] = {};

			//String parameter
			Class[] paramString = new Class[1];	
			paramString[0] = String.class;

			//Double parameter
			Class[] paramDouble = new Class[1];	
			paramDouble[0] = Double.TYPE;
			*/

			//Long parameter
			Class[] paramLong = new Class[1];	
			paramLong[0] = Long.TYPE;
			
			// lets find out what the number is in words
			method = cls.getDeclaredMethod(number2TextMethod, paramLong);
			outputtext = (String)method.invoke(obj, val);
		}
		catch(Exception ex)
		{
			/*
			ex.printStackTrace();
			System.out.println(ex.toString());
			System.out.println(ex.getLocalizedMessage());
			*/
			throw ex;
		}
		
		return outputtext;
	}
}

Lines 15-17 actually lookup the class that we will need for this method.  This will be the actual language class (ie English).  Lines 34-35 prepare the type of parameter that will be used by this method as well as performing the lookup of the method with the getDeclareMethod call.  Lines 38-39 simply calls this method with our parameter.

The actual language implementations are actually rather sparse.  Having the code to convert 73626.82 into either either German or English although interesting doesn’t actually reinforce anything related to reflection so it has been simplified.

package com.acmesoft.support;

public class en implements languageInterface 
{
	public String numberToText(long val)
	{
		String retval = "";
		
		switch ((int)val)
		{
		case 1:
			retval = "one";
			break;
			
		case 2:
			retval = "two";
			break;
			
		case 3:
			retval = "three";
			break;
			
		default:
			retval = "unknown";
		}
		return retval;
	}
	
	public String numberToText(double val)
	{
		return "not yet";
	}
	
	public void testPgm(String[] args)
	{
		int val = 2;
		String valText = "";
		
		if (args.length != 0)
			val = Integer.parseInt(args[0]);
		
		try 
		{
			valText = numberToText(val);
		} 
		catch (Exception e) 
		{
			e.printStackTrace();
		}
		
		System.out.println(val + " is equal to " + valText);

	}
	public static void main(String[] args)
	{
		en pgm = new en();
		pgm.testPgm(args);
		return ;
	}
}

There is nothing in this class “en” sample code that you won’t be able to recreate in perhaps in the first few days of introduction to Java.  It is only a few lines of reflection code in our Number class that provides the flexibility.

#!/bin/bash

CP=base/final/internationalBase.jar:german/final/internationalDE.jar:english/final/internationalEN.jar:.

java -cp $CP com.acmesoft.support.TestPgm  1 en de fr
echo " "
java -cp $CP com.acmesoft.support.TestPgm  2 en de xx
echo " "
java -cp $CP com.acmesoft.support.TestPgm  3 en de

testrun

Download complete source for this language example

Download files

The darker side of reflection

The ability to get either the value or method directly is much more powerful than it appears at the first glance.  It is actually possible to retrieve values from private variables or call private methods that you normally wouldn’t have access to.

The neat thing about this is you only need to add one additional method call to enable the actual access to the value or method.

For Private methods

Method method = yourObject.getClass().getDeclaredMethod(yourMethod, argumentTypes);
method.setAccessible(true);
return method.invoke(yourObject, yourParameters);

For private fields

Field field = yourObject.getClass().getDeclaredField(yourField);
field.setAccessible(true);
field.set(yourObject, value);

Ignoring access permissions example

package payroll;

import java.lang.reflect.*;

public class Interrogate {

    public void showIncome(PayrollDept myobject)
    {
        Field privateIncomeField = null;
        
        try {
            privateIncomeField = myobject.getClass().getDeclaredField("income");
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (SecurityException e) {
            e.printStackTrace();
        }
        double income = 0;
        try {
            privateIncomeField.setAccessible(true);
            income = privateIncomeField.getDouble(myobject);
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        System.out.println("Income " + income);
    }
    
    public void hackIncome(PayrollDept myobject)
    {
        Field privateIncomeField = null;
        
        try {
            privateIncomeField = myobject.getClass().getDeclaredField("income");
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (SecurityException e) {
            e.printStackTrace();
        }
        double income = 0;
        try {
            privateIncomeField.setAccessible(true);
            privateIncomeField.set(myobject, 1000000.0);
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }

    }
    
    public Interrogate()
    {
        PayrollDept myobject = new PayrollDept();
        
        System.out.println("Name   " + myobject.firstName + " "+ myobject.lastName + ", " + myobject.title);
        System.out.println("Eyes   " + myobject.eyeColor);
        System.out.println("Height " + myobject.height);
        System.out.println("Weight " + myobject.weight);

        showIncome(myobject);
        hackIncome(myobject);
        showIncome(myobject);
        
        Method increaseIncomeMethod = null;
        Class[] paramDouble = new Class[1];
        paramDouble[0] = Double.TYPE;
        try {
            increaseIncomeMethod = myobject.getClass().getDeclaredMethod("setIncome", paramDouble);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (SecurityException e) {
            e.printStackTrace();
        }
        try {
            increaseIncomeMethod.setAccessible(true);
            increaseIncomeMethod.invoke(myobject,2000000.0);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    
        System.out.println("Income " + myobject.verifyIncome());
    }
    public static void main(String[] args) 
    {
        new Interrogate();
    }
}
package payroll;

public class PayrollDept extends Object
{
    public String title ;
    public int height;
    public String eyeColor;
    public double weight;
    public String firstName;
    public String lastName;
    private double income ;
    
    public PayrollDept()
    {
        title = "CEO";
        height = 204;
        eyeColor = "hazel";
        weight = 90;
        income = 1000;
        firstName = "Max";
        lastName = "Musterman";
    }
    
    private void setIncome(double val)
    {
        income = val;
    }
    private double getIncome()
    {
        return income;
    }

    public double verifyIncome()
    {
        return income;
    }
}
#!/bin/bash

CP=final/darkside.jar

java -cp $CP payroll.Interrogate

darksidetest

Download complete source for this “darkside” example

Download files
Posted in programming | Tagged | Leave a comment

Security in homogeneous systems

The Central Intelligence Agency (CIA) has been quite industrious in creating a new way[1] of tracking documents that could be “borrowed” from a person, business or government against the will of of that entity.

This new document protection is the creation of a watermark that is also a web beacon in the document.  If you think about it, this is a pretty neat way of “bugging” a document to call home when it is opened.

This particular trick works (at the moment) only on Microsoft Office files.  Not a very surprising choice considering the market penetration of MS office.  I cannot find any usage statistics for MS Office but it seems reasonable that Microsoft has at least 50% of the overall market including personal usage and business usage.  I would bet that the business usage for medium and large sized company’s is much much higher.  There are some big firms and governments that use open source office suites but many more that use Microsoft Office solutions.

However, those ambitious CIA fellows must have had a blind spot in considering that people would only use MS products.  This probably doesn’t work when you open these documents with other office suites.  Not only that this foreign intrusion may actually be visible.  Oops.  I guess once they think this through to the end they will realize that was a bit of a silly assumption on their part.

Heterogeneous for the win

It is really a lot easier to support a company or division when everything is the same.  You have a few default images for the few types of systems.  In this situation, setting up a computer is really easy.  Really easy is not always the best solution.

All software has bugs and it is only a matter of time before some hacker or state agency finds a zero day bug they can exploit.  If all systems are using the same operating system then once a bug is found it would allow the hacker the ability to exploit it everywhere.  If some of the systems utilize a different operating system they would form type of firebreak against the exploit and help to make it safer.

Having different systems or programs can make support a bit harder but it will add subtle layers security at the minimum.

I thought that there were more articles about the dangers of homogeneous systems but Google cannot seem to find them.

Well, other than this white paper.

Read more: Whitepaper: Attack of the Clones – Is Homogeneity in a network environment safe?

 

Posted in Soapbox | Tagged , , | Leave a comment

The power of mathematics in government

DEBT

This is a word that you rarely hear mentioned much by politicians especially if they are campaigning for office.  Oh, sure you might hear something about how they will fix the deficit.  The deficit that the other guys have allowed to run rampant will be fixed.

Oh, sure we will cut the deficit by about 10% a year and then in about 10 years we will have that nasty deficit tiger tamed.  Usually the savings are conjured up by playing up how growth and thus tax receipts will be increased.

During an election when people or groups claim that these savings are either unlikely or not realistic.  These nay sayers are usually accused of being partisan.  Indeed this might be true but considering how optimistic politicians are (every single time) and how often they are incorrect – again virtually every single time maybe some pessimism is warranted.

How big of a deal is a 500 billion dollar deficit when compared to a 19.8 trillion dollar economy?  Well, people have been hearing about the deficit so much they have forgotten that it really means unpaid bills or borrowed money.  These small (ha) deficits are what keep adding up to mountains of debt.

budget deficit when your expenses exceed your income.
debt the sum of all of the money owed.  these values are essentially the sum of all budget deficits.

It would take a real concerted effort to pay any large debt it off and downright impossible without reducing the budget deficit to zero.

But it this really a problem? Perhaps it isn’t a problem with these low interest rates.  The Fed rate is currently at 1/2%.  In one sense this debt bomb is less of a problem with low interest rates but it isn’t the principle that will be the eventual problem but the interest.

I considered writing up a spreadsheet to try and describe the future evils that will be visited upon the US, but the Internet Wallstreet Journal has already done some looking into this issue.

https://blogs.wsj.com/economics/2015/02/03/the-legacy-of-debt-interest-costs-poised-to-surpass-defense-and-nondefense-discretionary-spending/

If you choose not to read the article, then at least read the headline.

The Legacy of Debt: Interest Costs Poised to Surpass Defense and Nondefense Discretionary Spending

This type of problem is not only limited to the US, one of the key weaknesses of the Maastricht was that deficits needed to be limited to 3%.  Limited to 3% pretty much gives the EU members the option of never really balancing their budget.

Politicians have a tendency ignore anything that they really don’t wish to address.  The key sentence for the Europeans.

annual deficits no greater than 3% of GDP

Sure, 3% is a small number but if it is left to grow at this amount even a 3% growth will cause the debt to double in about 25 years – assuming no unexpected circumstances increase the deficit.  Well, I am sure that the EU countries are making sure that in some years they have a surplus – right?

I am a tech guy (not a banker) but it is pretty disappointing to occasionally hear comments from people who cannot tell the difference between deficit and debt, and (US) politicians that play on that.

There will be some real problems for big countries that have never had to make hard decisions on their budgets if things don’t change.

Tell your friends the difference, tell your family the difference or perhaps most important tell your politician the difference (and that it matters to your children and their children).

 

Posted in Soapbox | Comments Off on The power of mathematics in government

… and because perception matters

“I am from the government and i am here to help”

                                            Ronald Reagan

It has certainly been a while since the government or the career politician has received a lot of respect.  I don’t find any statistics going back more than a few decades but it turns out that US politicians, especially congressman, end up much lower in the ranking over time.

Congress approval ratings in 2017             20%

Congress less popular than                           France

I don’t really want to defend the career politician but in this day and age their job is much tougher than when some of their predecessors such as when Abe Lincoln was in office. Actually, today it is even much harder than some of the more recent office holders such as Reagan or Clinton.  With the rise of technology their previous votes, speeches, or other misdeeds that have occurred in the last months, years or decades now come back to haunt them – sometimes in the form of video.

If you thought it was tough living down something you did in your youth imagine your every move being recorded for later use by groups just looking to find discrepancies or “flip flops” of opinion.  In addition, people or groups with personal agenda’s use all of this information with the intent of causing a politician to look stupid or clueless.

If you think that dealing with facts if difficult then try to imagine dealing perception.  It is just as powerful but not always grounded in facts.  There is even a trading adage to this effect.

Buy the rumor, Sell the fact

It is because perception is so powerful that small companies as well as large companies struggle hard to shape perception.  No CEO wants to loose customers or market capitalization because the public perceives them to be ambivalent about some topic or other – perception matters.

James Comey may have been fired for a lot of reasons but the reason that most people are looking closely at is that he was investigating the Trump campaign into collusion with Russia.

Were there any good reasons for firing James Comey?  Probably. What this the right time to do so? I suspect that historians will be answering these questions for years to come but this firing could be adding to the public perception that President Trump has something to hide.

This one firing would not necessarily matter so much if it was the only thing that has occurred during President Trump’s brief tenure as President.

In fact President Trump should be happy that special prosecutor Robert Mueller has been brought in to finish this task.  If for no other reason than it helps to refute the perception that there is anything that needs to be hidden, because perception matters.

It actually does not help President Trump’s case when he is exercising his hyperbole in some of his statements about this current situation.

The people who were happy with President Trump may or may not be less happy with him now. For those people who either did not like him before or had neutral feelings the various storms whirling around the White house do make a difference in how he is perceived as well as how America is perceive abroad.

I could take a cheap shot and find some reference from Donald Trump the campaigner to try and make him look less dignified or poke fun at him.  Instead, perhaps he will take some advice from someone he truly does trust.

Well, because perception does matter.

 

Posted in Soapbox | Tagged | Comments Off on … and because perception matters

professionalism in IT … at the movies

My first boss was a real ball-breaker.  He had a very good idea of what was possible with computers, what the users might need and how to achieve that.   He could have literally done it all himself except there were not enough hours in the day – so he needed staff.  When his staff had problems and needed assistance you could come to him for help.

First and foremost, when you show up, wait for him to finish what he was working on.  At the time it seemed like a power move but after years of reflection it was so he could finish whatever debugging he was in the middle of.  It takes longer than you would think to be in the zone and it is easy to get knocked out.

He would have expected that you had at least done your homework.

  • be able to clearly describe the problem
  • have the exact error message at hand
  • demonstrate what you have done in an attempt to correct this problem
  • be prepared to describe what you have done
  • know the code you bring to him

If you weren’t prepared the meeting probably wouldn’t go all that well.  He helped to cement how I would work on problems and what level I would expect from my colleagues.

I have a tendency to think about him whenever I see what I consider to be stupidity in the workplace.  I was surprised when I almost heard his voice at the movies.

It seems sloppy that in 2016 computers and point of sale terminals should be providing less information now than they probably did in the 1950’s.

cinestar-receipts-concessions

Concession receipt for 2 sodas and some popcorn

It my be difficult to see but this scanned receipt is a reasonably high res receipt that includes special symbols, German special characters, and bar codes.

I am a bit surprised how the number of items is represented.  I personally don’t think that the concession stand will be selling double digit of anything much less four digits of anything.  Someone decided they want all of their numbers to align so that isn’t the oddity but the leading zeros are.  Perhaps that is just a personal dislike.

The receipt itself actually has more information about the company and the branch than the food.  I know that snacks at the movies are expensive but from looking at this receipt it is almost as if the movie theater is embarrassed to say just how expensive each item truly was.

It is a possibility that receipts in Germany are more of the simple variety, but alas that isn’t the case.

tedi-receipt

receipt for USB cable and a flashlight

 

This is a receipt from a store that would be most like a dollar store in the USA.  This receipt contains as much information about the store in general as well as a lot of information about what was purchased.  The item #, description and cost per item is all clearly displayed.  Closer to the bottom you can even see how much of your purchase went to the government in the form of taxes.  This is a great receipt.

Taking one final look at my concession receipt

Dies ist keine Rechnung im Sinne des §14 UStG…

Well, I guess the receipt that I asked for is a receipt but not a receipt in the sense of what is a receipt as described by a long and dry law description clarified by §14 of UStG.

It is not like this particular movie theater cannot produce more complicated output.  They did a much better job with the tickets – font size, German characters and QR codes.

cinestar-receipts-seats

These are actually both the receipt and the ticket.  Plenty of information here as well including a nifty QR code which probably contains all of this and more.

If worked on the concessions output then my boss would be pulling me aside right now for a small talk.

Posted in Soapbox | Comments Off on professionalism in IT … at the movies

Is Agile development the Emperors new clothes

I had the opportunity to take a class on Agile development recently, Scrum, and it was a fascinating way of doing development. I have been pretty lucky over my career that I have not been dragged through a lot of heavy development processes. Yet, while working on some projects I have experienced the joys of slow processes, excessive meetings, indecisive users, as well as plenty of scope changes. Management would blame us if we didn’t deliver on time something that was completely different than their original program.

Initially while sitting in my class I was thinking that Scrum might be the solution to all those problems.

No specific due date is given for delivering on those features, just a series of releases each with more functionality than the last. There is no real penalty for change, well not for the developer; Perhaps for the product manager depending on the company culture. You even have your own advocate to deal with either incidental or structural problems.

About the time that I was convinced Scrum was the solution to all problems everywhere that I started to have a few doubts. I personally am not a big fan of writing up specifications or user documentation and the people have a tendency to not read it much either. This much unloved type of documentation is however requested by auditors.

I asked about this in class and oddly enough documentation was not one of the artifacts of the process. Sure, you could define “done” to include this but developers are not natural writers and from a productivity standpoint you would really want them to write code. What about adding a layer around the scrum team of technical writers?

That might be just as bad as not doing scrum in the first place. You will have a constant flow of people waddling over to the developers breaking their concentration.

Then why does Scrum work?

  • The developers set their own due dates rather than management
  • A product manager is available to answer all questions about the tasks being developed
  • The product manager can make decisions regarding the direction of the product
  • The number of meetings for the most part are all defined and limited
  • The developers are expected to be capable, independent and have courage
  • The scrum master is dedicated to eliminating impediments to team progress
  • The list of features have been ordered by priority and the important ones should be well defined.

The transparency helps management to realize that with the resources in place some of their requests are not possible.

What development methodology wouldn’t be better with these as preconditions? If you have dedicated group of smart people doing the work who are able to get feedback on their work along with someone fighting to remove difficulties then you will see good results.

Just like all other processes in the world the better your inputs the better your final results.  These results could be faster, smaller or less bug laden.  I guess this could be summed up with use better staff and try and stay out of their way … well, that’s my thoughts on agile.

 

 

Posted in Soapbox | Tagged | Comments Off on Is Agile development the Emperors new clothes

Restful services in Java – 360 degree of restful client

Always try and use the most appropriate tool for the task.  The Apache HTTP server or web server is a program for serving the html web pages to the client who requests them. Tomcat is a application server that is actually used to for serving up Java Servlets or JSPs that are packaged up in a Web Archive file (war).

That isn’t to say that Apache cannot serve up Java Servlets nor does it mean that Tomcat cannot serve up static html pages.  Both programs exist because each is specialized for their particular task.

However, in order to create my web client I am going to have Tomcat serve up both the application as well as the static html web page that calls this service.  In order to do that, I will need to make a small change to my Tomcat configuration so it can also serve up these static pages.

Static Setup

Tomcat is configured by default for Java Servlets but by adding a tiny bit of extra configuration it will then serve up the static pages.

In the Tomcat configuration directory /opt/tomcat/conf is the server.xml file which contains a lot of the configuration for Tomcat.  Simply adding the following line to the Host block will define the location for the static web pages.

<Context docBase="/opt/tomcat/webapps/test" path="/test" />

The docBase attribute points to the path where the static html will be located while the path attribute is the prefix for the web page.  With the above setup, the following would be the url to access the index.html page.

http://localhost:8080/test/index.html

This block actually contains more interesting configuration that should probably be explained.

 <Host name="localhost" appBase="webapps"
             unpackWARs="true" autoDeploy="true">

    <!-- SingleSignOn valve, share authentication between web applications
         Documentation at: /docs/config/valve.html -->
    <!--
         <Valve className="org.apache.catalina.authenticator.SingleSignOn" />
    -->

    <!-- Access log processes all example.
         Documentation at: /docs/config/valve.html
         Note: The pattern used is equivalent to using pattern="common" -->
    <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
           prefix="localhost_access_log" suffix=".txt"
           pattern="%h %l %u %t &quot;%r&quot; %s %b" />

    <Context docBase="/opt/tomcat/webapps/test" path="/test" />
 </Host>

The autoDeploy attribute gives the flexibility of deploying a war file while Tomcat is running.  This is actually pretty neat, you don’t need to stop and restart the server when installing the new war files.  Simply copy the war file to the webapp directory.

While doing some of my testing I simply would remove the war file and the directory that was unpacked from it.  After that I would copy over the new war file and wait for a few seconds.  At this point I could then call my restful service again.  Tomcat would unpack the new war file and then run the application.

Web Client

My client is really lightweight.  It simply queries the starting index and count of how many items should be retrieved.

Simply enter the values that you are interested in and click on the “fetch data” button.

The actual html for the webpage itself is trivial.  It simply makes the restful call and then parses the return list and displays each item.

The tricky part is not displaying the fields, gather the input or the button but actually the java script behind the webpage to make the AJAX call.  I am not a web developer so I will just try and point out the interesting things for the AJAX call.

360 Web Client Code

<!DOCTYPE html>
<html>
 <head>
 <meta charset="UTF-8">
 <title>JavaScript &amp; jQuery - Chapter 8: Ajax &amp; JSON - Loading HTML</title>
 <script src="js/jquery-1.12.1.js"></script> 

 <script>
 function displayname() {
 var start = document.getElementById("startidx").value;
 var count = document.getElementById("count").value;

  var xhr = new XMLHttpRequest(); // Create XMLHttpRequest object
 var myurl = "";
 myurl = 'http://localhost:8080/ThirdRestful/price/fetch?start=' + start + '&count=' + count;

  xhr.open('GET', myurl, false); // Prepare the request
  xhr.send(null); // Send the request
 
  responseObject = JSON.parse(xhr.responseText);
 
 var newContent = '';
 newContent += '<table align="left">';
 newContent += '<tr>';
 newContent += ' <th align="left">Id</th>';
 newContent += ' <th align="left">Symbol</th>';
 newContent += ' <th align="left">Bank</th>';
 newContent += ' <th align="left">Price</th>';
 newContent += ' <th align="left">Exchange</th>';
 newContent += ' <th align="left">Quote Timestamp</th>';
 newContent += '</tr>';

 for (i = 0; i < responseObject.records.length; i++)
 {
 newContent += '<tr>'; 
 newContent += '<td width="55px">'; newContent += responseObject.records[i].id; newContent += '</td>';
 newContent += '<td width="95px">'; newContent += responseObject.records[i].symbol; newContent += '</td>';
 newContent += '<td width="95px">'; newContent += responseObject.records[i].bank; newContent += '</td>';
 newContent += '<td width="95px">'; newContent += responseObject.records[i].price; newContent += '</td>';
 newContent += '<td width="105px">'; newContent += responseObject.records[i].exchange; newContent += '</td>';
 newContent += '<td width="255px">'; newContent += responseObject.records[i].quoteDateTime; newContent += '</td>';
 newContent += '</tr>'; 
 }
 newContent += '</table>'; 

 document.getElementById('content').innerHTML = newContent;
 }

 </script>

 </head>
 <body>

 <header><h1>360 WebClient </h1></header>
 <br />
 <label>Start Index: </label> <input type= text id="startidx" value="0" >
 <label>Count: </label> <input type= text id="count" value="10" >
 <input id="fetchdata" type="button" value="fetch data" onclick="displayname();" />
 <br />

 <p id="content"></p>
 <br />

 </body>
</html>

AJAX is Asynchronous JavaScript and XML which is how you can call your, or someone else’s web services.  This is neat because you can then create a fairly complicated page but by using AJAX you can pull in other information on demand to create a more interactive web experience.

I am pulling in all of this via the JavaScript library JQuery.  JQuery is not the only JavaScript library but it is one of the most popular ones.  It is possible to get either a compressed or uncompressed version of this library from the JQuery site.

https://jquery.com/download/

My web client allows the user to enter things that interest them and submit that as parameters to the restful web service.  The web service could itself go to the internet, read information from a database or perform some calculations – when it was finished that information could be returned to the calling client.

 myurl = 'http://localhost:8080/ThirdRestful/price/fetch?start=' + start + '&count=' + count;

More specifically, my example queries the values from the user and builds the URI that will call my service with the parameters in their proper locations.

This code is actually very optimistic as it assumes that the user will be smart enough to enter valid values into both fields before pressing the fetch data button.  It also assumes that data will exist.

This last assumption is a bit of a stretch as this is not a bullet proof production program but rather a proof of concept.

Creating test data

Rather than force myself to manually enter the data each time I start my server I have created a restful call to create some data.  This is done by simply calling the following URI.

http://localhost:8080/ThirdRestful/price/generate

This will generate some somewhat random data in order to better test my client. It is also possible to call this method with a parameter to generate more than the default 20 entries. It is possible to call this method any number of times.  The newly generated data will be added to the internal list.

http://localhost:8080/ThirdRestful/price/generate?count=10

The generate method will return the count of the number of items that exist in the list after adding the new day.

This is my last blog article about restful web services for the moment.  This is not the only way to create such services but it is a pretty easy way without having hundreds of additional java classes that make up some frameworks.

I think that this is a superior way of generating web services but any critics could easily point to the fact that it is not easy to know what services exist for my particular application – and they are correct.

Another way of producing web services that allow you to see what services are available is to use WSDL .  This will describe the web services and it also allows you to generate code which can be used to call each of the defined services.

I did have an opportunity to do just this for connecting with SharePoint.  I wasn’t really a big fan of the technology I was given.  There were hundreds of lines of auto-generated code and hundreds of files of odd framework code.  I suspect that some of the other frameworks out there (ie Spring) also have hundreds of new files but probably in a much better organized way.

I may end up checking out one of these other frameworks at some point, but for right now I will enjoy both the power and simplicity of the small Jersey powered restful server technology.

Posted in programming, Setup From Scratch | Tagged , , | Comments Off on Restful services in Java – 360 degree of restful client

Restful services in Java – 360 degree of restful server

This is the blog final entry for a restful service web server.  I have attempted to create more than your typical “foo” “bar” type example program. My final blog on restful services will be a fairly complete service that could be used to provide price data supplied by several “banks” on various exchanges.

The data can be  pseudo randomly generated to be later retrieved and displayed by web browser using java script to fetch, extract and display the data from a JSON formatted string.

A real production server would save server data in a more permanent manner such as a database or even perhaps files if the data lent itself to that. I didn’t feel like creating database so I have skipped over this step by adding a restful service for generating some data which is stored in memory. This is just a “temporary” server that is available for testing and not for real permanence.

This example server has the following methods.

  • generate
  • count
  • (index).xml
  • (index).json
  • (index).text
  • fetch
  • addOne
  • retrieve
  • retrieveall

The generate method is perhaps the most important of these for testing. Simply call this restful service in the beginning to generate twenty items by default or pass in a specific count to generate that many test items.

The generated data is put into a simple hash with the key to the hash being the simple index.

To look at the data that is in the hash the count, (index).xml, (index).json or (index).text.

The fetch method is actually the other main method specifically for a web client. This web service will retrieve an array of market prices in JSON format.

In a few days I will be providing a html client that will use this server and retrieve the data in the JSON format and display that to the web page.

PriceServer.java

package com.acmesoft;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;

import java.math.BigDecimal;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.HashMap;
import java.util.Iterator;

import javax.ws.rs.Consumes;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;
import javax.ws.rs.WebApplicationException;

@Path("/price")
public class PriceServer
{
	// should really be a database
	private static HashMap<Integer,MarketPrice> pricedatabase = new HashMap<Integer,MarketPrice>();
	private static int databasecount = 0;

	//
	// index is the actual 0 - n-1 of the map.
	//
	private String rangeAsXML(int start, int stop)
	{
		String retval = "";
		retval += "";

		for (int idx = start; idx <= stop; idx++)
		{
			MarketPrice item = null;
			item = pricedatabase.get(idx);

			if (item != null)
				retval += item.xmlString();
		}

		retval += "";

		return retval;
	}

	//
	// index is the actual 0 - n-1 of the map.
	//
	private String rangeAsJSON(int start, int stop)
	{
		String retval = "{ \"records\": [";

		for (int idx = start; idx <= stop; idx++)
		{
			MarketPrice item = null;
			item = pricedatabase.get(idx);

			if (item != null)
			{
				if (idx != start)
					retval += ", ";
				retval += item.JSONString();
			}
		}

		retval += "] }";

		return retval;
	}

	// initialize the price cache, this is pretty much only for debugging
	// 
	// this will generate 20 items by default
	// http://localhost:8080/ThirdRestful/price/generate
	//
	// this will generate 100 items instead 
	// http://localhost:8080/ThirdRestful/price/generate?count=100
	@GET
	@Path("/generate")
	@Produces( {MediaType.APPLICATION_XML})
	public Response generate(@Context UriInfo ui, @DefaultValue("20") @QueryParam("count") int debugcount) throws URISyntaxException
	{
		String path = ui.getAbsolutePath().toString() ;
		URI uri = new URI(path);

		MarketPrice newprice = null;
		for (int idx = 0; idx < debugcount; idx++)
		{
			switch (idx % 5)
			{
			case 0:
				newprice = new MarketPrice("EUR/USD", "DBK", new BigDecimal(1.056), "DTB");
				break;
			case 1:
				newprice = new MarketPrice("GBP/EUR", "BCY", new BigDecimal(1.179), "LIFFE");
				break;
			case 2:
				newprice = new MarketPrice("USD/MXN", "C", new BigDecimal(19.1), "CME");
				break;
			case 3:
				newprice = new MarketPrice("EUR/USD", "0UB", new BigDecimal(1.059), "SOFFEX");
				break;
			case 4:
				newprice = new MarketPrice("VEF/USD", "JPM", new BigDecimal(0.1001), "NYSE");
				break;
			}
			newprice.setId(databasecount);
			pricedatabase.put(databasecount, newprice);
			databasecount++;
		}

		//return Response.created(uri).contentLocation(uri).status(Response.Status.OK).build(); 
		return Response.created(uri).contentLocation(uri).status(Response.Status.OK).entity("" + databasecount +"").build(); 
	}

	// get the count of items
	// 
	// http://localhost:8080/ThirdRestful/price/count
	@GET
	@Path("/count")
	@Produces( {MediaType.APPLICATION_XML})
	public Response count(@Context UriInfo ui) throws URISyntaxException
	{
		String retval = "" + databasecount + "";
		String path = ui.getAbsolutePath().toString() ;
		URI uri = new URI(path);

		return Response.created(uri).contentLocation(uri).status(Response.Status.OK).entity(retval).build();
	}


	// add a new price record
	// 
	// http://localhost:8181/ThirdRestful/price/addOne 
	@POST
	@Path("/addOne")
	@Produces( {MediaType.APPLICATION_XML})
	public Response addOne(	@Context UriInfo ui, MarketPrice item) throws URISyntaxException
	{
		String path = ui.getAbsolutePath().toString() ;
		URI uri = new URI(path);
		return Response.created(uri).contentLocation(uri).status(Response.Status.OK).build(); 

	}

	// returns a selection of records in xml format.
	// 
	// http://localhost:8080/ThirdRestful/price/retrieve
	@GET
	@Path("/retrieve")
	@Produces( {MediaType.APPLICATION_XML})
	public Response retrieve(	@Context UriInfo ui,
			@DefaultValue("0") @QueryParam("start") int start, 
			@DefaultValue("10") @QueryParam("count") int count) throws URISyntaxException
	{
		String retval = "";
		String path = ui.getAbsolutePath().toString();
		URI uri = new URI(path);

		if (databasecount == 0)
			return Response.created(uri).contentLocation(uri).status(Response.Status.REQUESTED_RANGE_NOT_SATISFIABLE).build();
		else
		{
			int end = start + count - 1;
			if (end > databasecount-1)
				return Response.created(uri).contentLocation(uri).status(Response.Status.REQUESTED_RANGE_NOT_SATISFIABLE).build();
			retval = rangeAsXML(start,end);
		}
		return Response.created(uri).contentLocation(uri).status(Response.Status.OK).entity(retval).build(); 
	}

	// returns a selection of records in xml format.
	// 
	// this will return 10 items starting with the first
	// http://localhost:8080/ThirdRestful/price/fetch
	//
	// start with index one for three items
	// http://localhost:8080/ThirdRestful/price/fetch?start=1&count=3

	@GET
	@Path("/fetch")
	@Produces( {MediaType.APPLICATION_JSON})
	public Response fetch(	@Context UriInfo ui,
			@DefaultValue("0") @QueryParam("start") int start, 
			@DefaultValue("10") @QueryParam("count") int count) throws URISyntaxException
	{
		String retval = "";
		String path = ui.getAbsolutePath().toString();
		URI uri = new URI(path);

		if (databasecount == 0)
			return Response.created(uri).contentLocation(uri).status(Response.Status.REQUESTED_RANGE_NOT_SATISFIABLE).build();
		else
		{
			int end = start + count - 1;
			if (end > databasecount-1)
				return Response.created(uri).contentLocation(uri).status(Response.Status.REQUESTED_RANGE_NOT_SATISFIABLE).build();
			retval = rangeAsJSON(start,end);
		}
		return Response.created(uri).contentLocation(uri).status(Response.Status.OK).entity(retval).build(); 
	}


	// returns all records in xml format.
	// 
	// http://localhost:8080/ThirdRestful/price/retrieveall 
	@GET
	@Path("/retrieveall")
	@Produces( {MediaType.APPLICATION_XML})
	public Response showall(@Context UriInfo ui) throws URISyntaxException
	{
		String retval = "";
		String path = ui.getAbsolutePath().toString() ;
		URI uri = new URI(path);

		retval = rangeAsXML(0,databasecount-1);
		return Response.created(uri).contentLocation(uri).status(Response.Status.OK).entity(retval).build();
	}



	// returns single record in xml format.
	// 
	// http://localhost:8080/ThirdRestful/price/34.xml
	@GET
	@Path("{idx}.xml")
	@Produces( {MediaType.APPLICATION_XML})
	public Response getIndexXml(@Context UriInfo ui, @PathParam("idx") int idx)  throws URISyntaxException
	{
		MarketPrice retval = null;
		String path = ui.getAbsolutePath().toString() ;
		URI uri = new URI(path);

		if (idx >= 0 && idx < databasecount) 
                { 
                        retval = pricedatabase.get(idx); 
                        return Response.created(uri).contentLocation(uri).status(Response.Status.OK).entity(retval).build(); 
                } 
                else 
                        return Response.created(uri).contentLocation(uri).status(Response.Status.REQUESTED_RANGE_NOT_SATISFIABLE).build(); 
        } 

        // returns single record in json format. 
        // 
        // http://localhost:8080/ThirdRestful/price/34.json 
        @GET @Path("{idx}.json") 
        @Produces( {MediaType.APPLICATION_JSON}) 
        public Response getIndexJSON(@Context UriInfo ui, @PathParam("idx") int idx) throws URISyntaxException 
        { 
                MarketPrice item = null; 
                String retval = ""; 
                String path = ui.getAbsolutePath().toString() ; 
                URI uri = new URI(path); 
                if (idx >= 0 && idx < databasecount) 
                { 
                        item = pricedatabase.get(idx); 
                        retval = item.JSONString(); 
                        return Response.created(uri).contentLocation(uri).status(Response.Status.OK).entity(retval).build(); 
                } 
                else 
                        return Response.created(uri).contentLocation(uri).status(Response.Status.REQUESTED_RANGE_NOT_SATISFIABLE).build(); 
         } 

         // returns single record in json format. 
         // 
         // http://localhost:8080/ThirdRestful/price/34.text 
         @GET @Path("{idx}.text") 
         @Produces( {MediaType.TEXT_PLAIN}) 
         public Response getIndexTEXT(@Context UriInfo ui, @PathParam("idx") int idx) throws URISyntaxException 
         {
                MarketPrice item = null; 
                String retval = ""; 
                String path = ui.getAbsolutePath().toString() ; 
                URI uri = new URI(path); 
                if (idx >= 0 && idx < databasecount)
		{
			item = pricedatabase.get(idx);
			retval = item.toString();
			return Response.created(uri).contentLocation(uri).status(Response.Status.OK).entity(retval).build();
		}
		else
			return Response.created(uri).contentLocation(uri).status(Response.Status.REQUESTED_RANGE_NOT_SATISFIABLE).build();
	}


}

MarketPrice.java

package com.acmesoft;

import java.io.StringWriter;
import java.math.BigDecimal;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.PropertyException;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

import com.google.gson.Gson;

import javax.xml.bind.annotation.XmlAccessType;;

@XmlRootElement(name="marketPrice")
@XmlAccessorType(XmlAccessType.FIELD)
public class MarketPrice 
{
	@XmlElement
	private int id;
	@XmlElement
	private String symbol;		// EUR/USD
	@XmlElement
	private String bank;		// DBK
	@XmlElement
	private BigDecimal price;	// 1.1222
	@XmlElement
	private String exchange;	// DTB, NYSE, CBOT
	@XmlElement
	private Date quoteDateTime;	// 2015-01-01 14:32:45.032


	public MarketPrice()
	{
		id = -1;
		this.symbol= "";
		this.bank = "";
		this.price = new BigDecimal(0.0);
		this.exchange = "";
		this.quoteDateTime = new Date();
	}


	public MarketPrice(String symbol, String bank, BigDecimal price, String exchange)
	{
		DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");

		this.symbol= symbol;
		this.bank = bank;
		this.price = price;
		this.exchange = exchange;
		this.quoteDateTime = new Date();
		String debugDate = dateFormat.format(quoteDateTime);

		id = -1;
	}

	public MarketPrice(String symbol, String bank, BigDecimal price, String exchange, Date quoteDateTime)
	{
		this.symbol= symbol;
		this.bank = bank;
		this.price = price;
		this.exchange = exchange;
		this.quoteDateTime = quoteDateTime;
		id = -1;
	}

	public void setId(int value)
	{
		id = value;
	}
	public int getId()
	{
		return id;
	}

	public void setSymbol(String value)
	{
		symbol = value;
	}
	public String getSymbol()
	{
		return symbol;
	}

	public void setBank(String value)
	{
		bank = value;
	}
	public String getBank()
	{
		return bank;
	}

	public void setPrice(BigDecimal value)
	{
		price = value;
	}
	public void setPrice(double value)
	{
		price = new BigDecimal(value);
	}
	public BigDecimal getPrice()
	{
		return price;
	}

	public void setExchange(String value)
	{
		exchange = value;
	}
	public String getExchange()
	{
		return exchange;
	}

	public Date getQuoteDateTime()
	{
		return quoteDateTime;
	}

	public void setQuoteDateTime(Date value)
	{
		quoteDateTime = value;
	}


	public String toString()
	{
		String retval = getCSVData();

		return retval;
	}

	public String xmlString()
	{ 
		String retval = toXmlString();
		retval = retval.substring(retval.indexOf("\n"));

		return retval;
	}

	public String JSONString()
	{ 
		Gson gson = new Gson();
		String JSONstr = gson.toJson(this);
		return JSONstr;  
	}

	public String toXmlString()
	{
		JAXBContext ctx = null;
		Marshaller maxMarshaller = null;

		try {
			ctx = JAXBContext.newInstance(MarketPrice.class);
		} catch (JAXBException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		try {
			maxMarshaller = ctx.createMarshaller();
		} catch (JAXBException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}

		try {
			maxMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
		} catch (PropertyException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}

		StringWriter writer = new StringWriter();
		try {
			maxMarshaller.marshal(this,writer);
		} catch (JAXBException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		String xmlPrice = writer.toString();

		return xmlPrice;
	}

	private String convertToTime(long milliseconds)
	{
		Date date = new Date(milliseconds);
		DateFormat dateformat = new SimpleDateFormat("HH:mm:ss.SSS");
		return dateformat.format(date);
	}
	public String getCSVHeader()
	{
		String delim = com.acmesoft.Constants.FIELDDELIM;
		String retval;

		retval = "Id" + delim + "Symbol" + delim + "Price" + delim + "Bank" + delim + "Exchange" + delim + "QuoteDate" ;

		return retval;
	}
	public String getCSVData()
	{
		String delim = com.acmesoft.Constants.FIELDDELIM;
		String retval;

		retval = id + delim + symbol + delim + price + delim + bank + delim + exchange + delim + quoteDateTime ;

		return retval;
	}
}

PriceCount.java

package com.acmesoft;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name="marketPrice")
@XmlAccessorType(XmlAccessType.FIELD)
public class PriceCount
{
        @XmlElement
        private int count;

        public PriceCount()
        {

        }
        public PriceCount(int val)
        {
                count = val;
        }

        public int getCount()
        {
                return count;
        }

        public void setCount(int val)
        {
                count = val;
        }
}

Constants.java

package com.acmesoft;

public class Constants {
	final public static String FIELDDELIM = ",";
	final public static int OK = 200;
	final public static String DATETIMEFORMAT = "yyyy-MM-ddHH:mm:ss.SSS";
}
Posted in programming | Tagged , , | Comments Off on Restful services in Java – 360 degree of restful server