jason w. jones

software from the trenches

Processing a file line by line in Java

I seem to use this pattern a lot, particularly in projects without dependencies (i.e., no Guava). What’s the cleanest way to iterate through a file line by line in Java? There are a lot of examples that are pretty messy. Here’s one I keep coming back to that is nice because it uses a traditional for loop to manage things. In this case it’s not just a counter variable but instead, a more general version of the for loop where we have an initializer, while condition, and iteration statement.

public void process(Reader reader) throws IOException {
  BufferedReader bufferedReader = new BufferedReader(reader);
  for (String line = bufferedReader.readLine(); line != null; line = bufferedReader.readLine()) {
    System.out.println("Line: " + line);
  }
  bufferedReader.close();
}
That’s it. That’s about as clean as I think I can get it. Note that the argument to the method isn’t a String filename but rather a Reader object, which alleviates the need for this method to have to catch FileNotFoundException as the caller would presumably supply a FileReader or some other type of Reader.

Pre-seeding Hyperion Planning User Preferences with values for a smoother user experience

Wow, I think I am actually writing an article on Hyperion Planning. I think pigs are flying right now. I have been helping out on a system upgrade for the last few months where we are in many ways “refactoring” a Planning deployment. I’m borrowing that term from the software world. In other words, we are changing how things work under the hood without the explicit intention of changing how things look to users. One of the changes we are making, however, is to introduce some variables for users to be able to change their Version and Scenario.

Just to be clear, the variables are the ones that are set in the preferences menu. And we’d like to provide some defaults so that the users have the most likely choices pre-selected. We can export the User Preferences option from LCM. The corresponding XML file has a section for each user’s variables. It’s like this:

<UserPreferences>
  <UserPreference UserName="jason">
    <!-- some stuff here -->
    <UserVariables>
      <Variable Name="Scen_UserVar" Value="Forecast"/>
      <Variable Name="Ver_UserVar" Value="Working"/>
    </UserVariables>
  </UserPreference>
</UserPreferences>

There’s, of course, a UserPreference section for each user. We can edit the variables here in this config file and the import it to the target system (or back into the current one) to fill the values. A couple of notes to consider:

  • If you try to strip out the other stuff in the UserPreference section so that it doesn’t get touched, it’ll just load defaults for that user. You might not want to blow out the user’s settings that way.
  • The reason for trying to do the above bullet item would be if you’re just trying to copy and paste the same block of code for each user.
  • A user in the target system might not be in the User Preferences export – you can create that manually by copying and pasting a different user.

It’s incredibly likely that there’s a better way to do this or some magical option I don’t know of somewhere that’ll take care of it, but I wasn’t aware of it and decided to “brute” force it. The copying/pasting and editing was the “hardest” part as I couldn’t think if this procedure could be reasonably automated in UltraEdit or Notepad++ or something, so I just did it by hand.

Hope this helps someone!

Flipping an ODI model to a different technology and kicking the interfaces

One of my recent ODI projects is a relatively complex transformation job. I am effectively building up a master/detail set of records from a single table. The single table isn’t really a single table in the source, it’s multiple tables. Within ODI I make several passes on it, dialing in the fields with interfaces and procedures. I opted to use the in-memory engine (MEMORY_ENGINE) because I thought the architecture would be a little cleaner, and the amounts of data being pushed through are not huge.

Everything was fine, until I hit a legitimate ODI bug. I actually found a relevant case in Oracle support for it: ODI-1228 “statement is not in batch mode”. There was even a patch! Unfortunately, the patch required a version of ODI higher than what I had available. So on a tight deadline my choices were to push through an ODI upgrade or to find some workaround.

I decided to see if I had a low-cost option of switching from using the memory engine to just using an Oracle schema as a stage (note that the package and interfaces themselves are all just moving data between various Oracle servers, nothing Hyperion related even). So I went into my model for the staging table that I was using, and just switched it from the In-memory Engine to Oracle (using the drop down). No complaints from ODI there.

Next I went into one of the interfaces that was previously setup to have source/staging/target in terms of its whole process. I went straight to the Flow tab but had some issues and fun little NullPointerException errors which is always a fun time. The thing is, I changed a technology on a model being used in various interfaces but it’s not like any part of ODI went into those interfaces to say “Hey, this changed…” – in fact, when you change the technology of a model, ODI helpfully and plainly just says “Hey, this is likely to break stuff. Proceed at your own risk… THAR BE DRAGONS.” Or something like that.

Anyway, I found that I could sort of ‘kick’ the interface when I opened it, by checking the “Staging Area Other Than Target” option, then turning it off again (it was off in most of my interfaces). This forced the interface to sort of recalculate and reset the flow, which took into account the updated technology of the model. There might be a better way to do this rather than this “fuzzy” method, but it worked and I didn’t have to redo the plethora of interfaces in this package.

Hopefully this helps someone else out someday!

WSDL XML tweak for Essbase Web Services for C#/Service Util

I just thought I’d make a small post on an issue I have encountered with Essbase Web Services. I also mention this during my webinar on the matter. If you use the svcutil.exe program to generate a set of proxy classes based on the WSDL file for Essbase Web Services, you’ll get an error.

At least as it pertains to the DatasourceService file, you need to make a small change. Here’s the problem line:

<xs:element default="DBALL" minOccurs="0" name="cubeAccess" type="tns:CubeAccess"/>

The problem is that it’s trying to set a default value for the CubeAccess property, but DBALL isn’t defined in the enumeration for this type. Here it is from later in the file:

<xs:simpleType name="CubeAccess">
 <xs:restriction base="xs:string">
 <xs:enumeration value="NONE"/>
 <xs:enumeration value="FILTER"/>
 <xs:enumeration value="READ"/>
 <xs:enumeration value="WRITE"/>
 <xs:enumeration value="CALC"/>
 <xs:enumeration value="DESIGN"/>
 </xs:restriction>
 </xs:simpleType>

There’s no DBALL in the above. We can actually just comment out the above line in the file or delete it all together to remove the reference to a non-existing enumeration value. I haven’t seen any problems from doing this. I’m hesitant at this point to try and introduce DBALL as an enumeration value since that doesn’t technically exist in the Oracle definition of the server, and I’m not sure what the right way to go in terms of setting a default value might be (i.e., should it be NONE or READ or other?).

In any case, for the purposes of proxy generation from the Visual Studio tool, just removing the reference seems to do the trick. Here’s what the commented line looks like, just for the sake of completeness:

<xs:element default="DBALL" minOccurs="0" name="cubeAccess" type="tns:CubeAccess"/>

Just tonight I verified that this issue seems to still exist in EPM 11.1.2.3.

That all being said, it’s possible that I’m just totally missing something there – perhaps an option on the proxy generation I need to turn on or something else, but I do know that commenting the line gets me to where I can successfully use the tool. If you’re more familiar with this than I am then please let me know if you have some advice.

Upcoming Webinar: Practical Essbase Web Services

Upcoming webinar, as in happening tomorrow! This webinar will be tomorrow, August 6th, at 11AM PST.

I am conducting a webinar tomorrow called Practical Essbase Web Services. This is mostly a re-presentation of my webinar in New Orleans for Kscope a couple of months ago. As with before, I’ll be taking a tour of the different connectivity options for getting to Hyperion and Essbase data programmatically, then jumping in to the Essbase Web Services component that has started being available as of version 11.1.2.2.

This is a bit of short notice but I wanted to invite anyone that reads this blog to attend. As with my ODI webinar a while back, we’ll be recording it so that it can be watched at your own time, but definitely attend if you are interested in this topic or want to ask some questions at the end.

The link to register can be found here. Wish me luck and I will hope to see you there!

Hyperion code drop: Parent Inferrer tool

I am pleased to release another small one-off Hyperion-related open-source tool into the wild: Hyperion Parent Inferrer. This Java program/library can be used to translate a space-delimited hierarchy file into one with explicit parent-child mappings. For example, consider the following input file:

Time
 Q1
  January
  February
  March
 Q2
  April
  May
  June
 Q3
  July
  August
  September
 Q4
  October
  November
  December

Hyperion Parent Inferrer will generate the following output:

null,Time
Time,Q1
Q1,January
Q1,February
Q1,March
Time,Q2
Q2,April
Q2,May
Q2,June
Time,Q3
Q3,July
Q3,August
Q3,September
Time,Q4
Q4,October
Q4,November
Q4,December

As with most of the things I release these days, this tool is just a cleaned up version of something that I needed or used once or twice. In this case I wrote this up to help with a conversion process at some time in the past.

Now, I’m not saying that the approach I had to take was ideal or there weren’t better solutions. But oftentimes the environment that we operate in is less than ideal and you just gotta find a way to duct tape everything together. Hence this tool. The code as it sits today works perfectly fine but does not provide much in the way of configurability or options that might make it useful in more contexts. But as with some of the other projects I have released, I thought it would be nice to toss this over the fence in case anyone can benefit from it.

If you find a use for this or want to show me your clever Python/Perl one-liner that does the same thing, let me know!

Hyperion Health Check Hit List

I am asking for your Hyperion wisdom again, oh beloved readers! In particular, I am soliciting information from you consultanty types and those of you who otherwise hop into a lot of different Hyperion systems.

Oftentimes a client needs help with speeding up an Essbase/Hyperion process/server/cube that has become unwieldy and slow. So you take a look at things. When you happen to hop in to an environment and assess its health, what do you look for, from a Hyperion point of view? For example, on BSO cubes I go right for the stats and check out the block density and average cluster ratio. From there I can go in any number of directions, looking at the overall outline, automation, cache settings, and so forth. So I have this already:

  1. Check block density and other cube stats
  2. Review outline for any red flags
  3. Check size of index cache with respect to the size of the index itself
  4. Take a look at outline for things that can be removed/deleted/dynamic calc, etc
  5. Ensure logs are not huge
  6. Look for XCP files, if any
  7. And a few others

I am really, really, curious if you have something you look for, particularly if it’s something you might dive into with EAS. I’m working on something interesting and your feedback is very appreciated! It can be anything at all: checking the server, checking the app or the cube, checking the file system, calc scripts, business rules, automation, and so on. Thanks!

ADS File Reader 1.0.0 released

As promised, I cleaned up the Java code for very easily parsing through files in the ADS format. ADS File Reader has an incredibly intuitive, clean, and functional API that makes parsing through ADS files a breeze. You won’t believe how easy it is to burn through an ADS file (if you have to). I can’t imagine that there are a ton of people out there that need to do this, but if you wind up having to (and especially if you need it in a larger Java program) then you should be all set. As with most of my other projects, ADS File Reader is licensed under the Apache Software License version 2.0 and is available on GitHub. For more information and a link to GitHub, check out the ADS File Reader project page.

Thanks to all of you that sent in some ADS files that I could play with. It definitely helped flush out a couple of kinks. If you end up using this library please let me know, and definitely let me know if you run into any issues.

Hyperion Essbase Papercut: EAS unable to save custom views

The Essbase Administration Services console has an ostensibly nice feature: custom views. Instead of having to navigate from the top of the hierarchy down to the thing you want to see, you can create a custom view at a lower level in the navigation tree. This is a custom view and it gets its own tab along with the normal enterprise view.

So… nice feature in theory. I used it a few times but now never really mess around with it. This is probably more to do with the fact that I jump in and out of a multitude of environments much more quickly these days than I ever used to.

In any case, it’s clear that EAS stores this setting in a database and on the server. This is also nice in theory because it means the settings you set aren’t locked to a particular machine and that you’d have to set everything back up if you ever installed EAS elsewhere. The console, however, takes its sweet time relaying your settings up to the server, though. In fact, it waits until you exit to sync things up.

In a perfect world, I am opening up EAS, doing what I need to do, then closing it right away. And perhaps this is how the creators envisioned it being used. But we don’t live in a perfect world, and I have a tendency to leave EAS and many other programs open indefinitely. For one reason or another I might lose my network connection and connection to EAS. Then I want to exit EAS, which is EXACTLY when it wants to talk to the EAS server… which it can’t. And EAS gleefully tells me that it can’t save my custom views. Even if I don’t have any. Which I don’t (see above).

Every time.

As a software developer this absolutely kills me on several levels. One being why don’t we just relay the preference at the time it’s set rather than on exit (which statistically is a very likely time for not having a connection to the server). Two, when I want to close a program I generally want to close-it-n0w-thankyouverymuch. Finally, three, there’s nothing I can do about the lack of setting saving going on anyway – so just silently log it, if you must, shut up, and shut down.

As I said, this is pedantic, but that’s the very definition of the notion behind this papercuts: no single one is bad but put together… ugh.

While I’m at it, a fresh coat of paint on EAS wouldn’t kill anyone either. Actually, last time I looked under the hood a bit I noticed that EAS was using some pluggable “LAF” (look and feel) architecture and I was able to tweak the colors a bit, away from “Interdimensional Irrelevance Grey” and “Low Block Density Cyan” but it’s been awhile since I played with things…

Do you have any ADS files you can share with me?

As you may have noticed I have a penchant for throwing my various Java and other language endeavors over the wall and seeing what happens. Most of these are open source programs ostensibly in the Hyperion Essbase space, but every day my focus seems to broaden a bit. I’ve open sourced data generators, validation tools, substitution variable updaters, and more.

The particular code that I am cleaning up now and getting ready to kick out as a small Java library for reading the ADS file format. Awhile back it was necessary for me to work with raw ADS files and use them as the input to another system. For those of you that aren’t familiar, the ADS file format is used by LCM when you kick out an EPMA dimension. I’m sure it’s used in other contexts too but this is just what I know it from. It’s not incredibly complex but it does have its nuances.

I’d like to be able to test it against some files other than some of my own, so if you have an ADS file laying around or can generate one that you can share with me so I can test with that too, I’d appreciate it. I will absolutely NOT distribute it with the rest of the program or otherwise share it with anyone else unless you explicitly say I may do so.

Thanks!