Oracle SQL Developer

I’ve just discovered Oracle SQL Developer, and it looks like it’s going to really make my life easier. I’ve been using an old, crusty version of SQL Navigator for my SQL visualization needs, and it’s always worked, but I’ve never been crazy about it. For one, the UI is very klunky — the mouse wheel doesn’t work, and it doesn’t auto-scroll when I expand collapsible lists. So I end up doing a lot of click-and-drag scrolling, which is annoying (keep in mind this is a really old version of the software; hopefully these issues have been resolved in more recent releases). And, the software is Windows-only, so I have to remote desktop into my Windows box to run it. This gives it a cramped feel, because the remote desktop has a lower resolution than my main display, and I can’t resize it to be as big as I want. And last but not least, our firewall requires me to run it over a VPN connection, and the VPN kicks me off after 12 hours, fubaring my connections and requiring me to restart it daily. Extremely annoying.

Enter SQL Developer. It looks promising. It runs on Windows, Linux and Mac. The GUI is much slicker than the version of SQL Navigator I was running. At the same time, Rob gave me the tip to run it over an SSH tunnel to a machine on the DB server’s trusted network, which means I can bypass the VPN. Wins on all counts.

Installation was straightforward, after I figured out how to point it at the correct JDK. It requires Sun’s JDK1.5, but it initially was ignoring my JAVA_HOME environment variable and using an older version. I poked around the initialization script and found that it was using the directory search path to find the JVM. I added the JDK1.5 bin directory as the first thing in my search path, and then it worked. Then I set up the SSH tunnel:

ssh trusted-host.umbc.edu -L 1522:oracle.server.umbc.edu:1522

After that, I was up and running. It looks great. Stay tuned for further impressions.

myUMBC redesign coming along

What’s this… a rare work-related entry on a weekend??

Well, it is the weekend, but I’m hacking on the portal anyhow, to get ready for our relaunch this August. It’s coming along marvelously, thanks mainly to Collier, but I’ve been busy with it too. The relaunch will include:

  • A complete redesign of the front end (users will think we did something 😉
  • Framework upgrade from uPortal 2.4.3 to uPortal 2.5.2
  • Switch layout managers from Aggregated Layouts (ALM) to Distributed Layout Manager (DLM)
  • A flexible development environment (built around CVS) that accommodates multiple developers and makes it easy to deploy from scratch

It’s an ambitious undertaking given the time frame, but it’s really coming together amazingly well. The new portal instance is up and running on our test server. Today, I got our “Local Connection Context,” (which provides connectivity to the legacy myUMBC perl codebase via web proxy channels) working. There were a couple “gotchas” with doing this. First off, I made the executive decision to point the test-instance web proxy channels at the production SIS data. Yeah, we do have a development SIS instance, but it’s a little too rough-around-the-edges to use for this purpose. For example, there’s no (reliable) FastCGI version running, and using the standard CGI stuff would absolutely kill the performance. And, we’re not really concerned with testing the SIS stuff on the test portal instance — we’re really more concerned with ensuring that the SIS stuff renders properly. To that end, it makes more sense to point to the stable, production SIS code, to get the closest approximation to what would be running in prod anyhow.

Doing this raises a problem, though — the portal is connected to the DEVL Oracle instance, but to render production content, I also need a connection to the PROD instance. In production, I only need one database connection; in devl/test, I’m going to need two. I handled this by adding an additional JNDI data source for the prod database, and adding code to the connection context to read the data source info out of a properties file. I called the data source ProdPortalDb (it’s defined in /properties/uPortal55.xml), and the properties file is /properties/myumbc.properties.

Stay tuned for more.

Pool coping project — getting started

Time to get started on the pool repair project.. better late than never I suppose. I’ve blocked off this coming Thursday to rent a concrete saw and cut back the expansion joint. Also, I’ve been thinking a lot more about what to use to mortar the coping stones in place. Terry Tamminen’s excellent book, The Ultimate Pool Maintenance Manual, includes instructions for making what he calls “patch mix”, using white portland cement and sand. He uses this same stuff (possibly with different ingredient ratios; I don’t have the book here to confirm) for patching plaster, anchoring coping stones, and grouting stones and tile. I think this might be the way to go, rather than buying premixed bags of mortar as I was originally planning. Just need to find a supplier. I’m not too confident that the big boxes will stock white portland. If not, I’ll try my favorite lumber yard. Will work on researching this over the next few days. (Update 6/22.. no sign of white portland at Home Depot).

Oh, and the loose strip of waterline tile in the deep end fell off all by itself two days ago. I had to dive in to fish it out. Remarkably, it stayed completely intact, leaving me with a roughly 2-foot strip of mortar and pool tile, and the beam behind it is fairly clean too. I need to decide if I want to try to re-attach it, or just start over and retile (I have plenty of extra tile, so either is an option). This is the last step of the project, and won’t be happening until fall when I can lower the water level, so I’ve got plenty of time to think about it.

[More:]

6/21: Informative posting on poolforum.com about setting pool tile.

6/22: Well, I decided to scrap my plans for the day due to unfavorable weather. However, I did go to Home Depot to take a better look at the concrete saw. I found out:

  • They supply all the fuel mixture I need (it’s a 2-cycle engine as I suspected)
  • There is roughly 5-6 inches from the blade to the outer edge of the dolly wheel on one side. This should be sufficient clearance to run the dolly along the pool coping edge. It will be helpful if the wheel height can be adjusted independently on either side to accommodate uneven surfaces.. but, I didn’t think to ask.
  • The saw includes a water feed, which is great because it should really help cut down on dust.
  • I don’t think it’ll fit in my car, so I’ll need to borrow my parents’ pickup.

Now, I just need to wait for the weather to cooperate, so I can get this done. Based on the 5-day forecast, I might be waiting awhile..

6/28: The crappy weather is finally moving out of the area, so the job is back on the calendar for Friday. Fingers crossed.

SSN Remediation is here

Woo-hoo! SSN Remediation happened over the past weekend, and we’re back up and running. I really think this is going to be a big win over the long term.

On the myUMBC side of things, there wasn’t much I needed to do. Just update my code in two places (one on the uPortal side, and another on the legacy Perl side) to go after the new “HP-ID” instead of the SSN. Then there were a few minor tweaks to some wording and input fields, and that was that.

This morning we brought all of our services back online, and turned them back loose on the masses. There were a couple hiccups:

  1. It broke PlacePro (I guess the real question here is, what doesn’t break PlacePro). Quick fix: a couple extra lines of code to pass the real SSN to PlacePro, rather than the HP-ID. Since we’re abandoning PlacePro in favor of another vendor, I doubt we’ll undertake a wholesale remediation effort with them; we’ll just cut over later this summer, and then have them wipe their database.I thought that the National Student Clearinghouse stuff would be similarly broken, but it turns out I implemented that totally separately and it appears not to be affected.
  2. I missed a couple places in the code where I was explicitly going after the socialSecurityNumber LDAP attribute, which broke a couple of things in minor ways. Another quick fix.

Other than that, things have been relatively quiet, and I’m just sitting around here waiting for the axe to fall. Keeping my fingers crossed..

Finally got in the pool

Better late than never, we took our first swim of the season today. It’s nice to finally be using the pool, because it makes the hassle of maintaining it seem more worthwhile. It’s not quite worth all the effort and expense IMHO, but still, it is nice to be able to hop in the pool on a hot day. And when it’s not full of leaves and other assorted crap, it’s nice to look at too.

I got a pleasant surprise when I uncovered the pool this morning.. the algae clinging to the diagonal hopper walls was almost totally gone. So, it appears that repeated brushing and superchlorination is the ticket to getting rid of this stuff. Apparently I don’t need a steel-bristled brush after all (although it may hasten the process, so I may pick one up anyhow). In future years, I’ll try to be a little more faithful with the off-season chlorination so the algae won’t take hold like it did this year.

Also, I made a test cut in the pool deck with my new diamond blade. And I must say, it cuts very easily — much more easily than I expected. As I suspected, the circular saw doesn’t cut quite deep enough. However, I can now go ahead and rent a larger concrete saw with the confidence that it’ll do the job. The current plan is to take a day off this week (work schedule permitting) and do it. Still not quite sure how I’ll do the curved sections. I’ll figure something out I hope.

Student Parking Registration

I should have seen the writing on the wall 5 years ago..

I’m busy fixing the online Student Parking Registration app, which has been sorta broken ever since the uPortal launch. Student Parking is a unique application. It’s the only app we have here that:

  • Communicates directly with the HP3000 mainframe via TCP sockets, and
  • Is not part of the monolithic ‘myUMBC’ Perl codebase.

Combine these two, and you get “never-ending headache”. Five years ago, when the app was written, I had vague misgivings about it being developed this way, but due to a combination of laziness and busy-ness, I didn’t say anything about it. So it went up, ran for five years, and broke with the new portal. And now, I’m stuck doing what should have been done with it from the start: I’m essentially rewriting it and building it into the myUMBC Perl codebase. Once that’s done, it’ll be reliable, it’ll have better error handling, it’ll deal with mandatory PIN changes, it’ll have a UI consistent with the rest of the myUMBC SIS functions, etc. etc. In a nutshell, it’ll work the way it’s supposed to, and I’ll be able to stop treating it like some high-maintenance colicky infant.

It doesn’t help that there are like 10 copies of the code floating around in various places, either. Half the fun was tracking down the version that was actually running in production…

Out with GUIDs.. in with Campus IDs

OK, policy decision for our up-and-coming launch of uPortal 2.5.. I’m going to stop using the LDAP GUID as the uPortal ‘unique username’, and use the new UMBC Campus ID instead.

Background: Every uPortal user gets an entry in uPortal’s user table, UP_USER. This table contains (among other things) a numeric ID for primary key, and a text ‘username’. Username is what uPortal uses as its security principal. For our current production installation of uPortal, we’re using the user’s LDAP GUID as the security principal. This works fine, but it causes problems with things like the Groups and Permissions manager, which allows you to search for specific usernames. The GUID is a long, unwieldy string that isn’t really human-friendly, so it’s not really something we want people using as a search key.

Now, why don’t we just use the user’s UMBC username as the security principal? Certainly seems logical. But, down the road, we want to provide access to the portal for alumni, prospective students, parents, etc. These people will not necessarily have a UMBC username. If we use that as a security principal, we effectively lock these people out of the portal. We need a unique identifier that everyone in the directory possesses. Until recently, the GUID was the only thing that fit the bill. Now, we have the nifty UMBC Campus ID, which is a simple string of two alphanumeric characters followed by five digits. Unlike GUID, the Campus ID is intended for human consumption (we actually display it on our ID cards). So, while it may not be quite as search-friendly as a username, it’s much more so than a GUID, and everyone in the directory has one.

Yet another happy byproduct of SSN remediation. I’m sure I’ll be cursing it next week after the SIS cutover, but I’ll say it again: In the long run, it’ll be well worth the hassle.

Followup… looks like if I want to do this, I’ll need to do an extra LDAP call to pull the Campus ID out of the PersonDB record. Not the end of the world, but not a 10-minute change either as I had hoped. I’ll have to come back to this later.

6/22: Looks like Rob is now including Campus ID in the Webauth ticket hash map. So, no extra LDAP query necessary. Cool…

New Boiler

So it looks like we’re going to take the plunge, and get a new boiler put in. Several things are driving this. For one, a detailed heat loss calculation has revealed that our current boiler, while reasonably efficient, is about twice the size it needs to be to heat the house. It has always short-cycled, which has a bunch of undesired effects.. uneven heat, loss of efficiency, bad for the boiler, etc. A properly sized boiler will save money and keep us more comfortable — an unbeatable combo.

The real, black-and-white measure of efficiency for an oil heat system, is the number of gallons of oil it consumes per heating degree day. This isn’t too difficult to measure empirically, using data from the oil company and the National Weather Service. Read your latest receipt from the oil company to see how many gallons were delivered at the last fill-up. Count how many days passed since the tank was last full, and divide by the number of gallons delivered to get the number of gallons burned per day. Then, go to the National Weather Service climate page, click on your state, and download the “Preliminary Climatology Data” for the time period in question. It’s published monthly. Add up the total number of heating degree days for the period, and divide by the number of days in the period, to get the number of heating degree days per day. Then, divide gallons per day by heating degree days per day, to get gallons per heating degree day. In theory, the lower this number, the better. I’ve been keeping track of our gallons per degree day usage with the current boiler, and it’ll be really interesting to see what effect a new boiler has.

[More:]

In an ideal test environment, gallons per degree day will give a perfectly accurate picture of a heating system’s efficiency for a given house. Unfortunately, there are a lot of factors that skew the measure, which make it hard to compare numbers from season to season. Among these are

  • Varying thermostat settings;
  • Other oil-fired appliances (in our case, a water heater);
  • Solar gain or lack thereof (not accounted for in the NWS data).

So it’s impossible to get a really precise measure, but this is about the best approximation we have. In our case, in just over 4 years (including 5 winters), we averaged 0.2 gallons per degree day. Our usage has trended down over the longer term, as we’ve added insulation and tightened the house up with new windows etc. However, this past winter our usage was up somewhat (roughly 0.03 gal/hdd difference, which doesn’t seem like much, but translates to 150 extra gallons over a 5000 hdd season). I’m not sure why this is — we even had our boiler downfired (from 1.25 to 1.10gph), which I would think would reduce our usage.

Our attempts to improve the house’s efficiency have had less of an effect than I had hoped, netting us maybe a .03-.05 gal/hdd difference or so per winter. I think (hope) a new boiler will have a more pronounced effect. We’ll see I guess. In any event, it’ll hopefully get rid of the uneven-heat problems which have plagued us all along with the current boiler.

Followup 7/25… Details on our new system.

Funny CVS Snafu

First the good news… we’ve decided to go to uPortal 2.5 for the fall, and switch from the buggy Aggregated Layout Manager (ALM) to the purportedly-much-better Distributed Layout Manager (DLM). I’ll be counting the days until ALM is history.

With that in mind, I pulled down a fresh copy of uPortal 2.5.2 and created a new CVS repository for it. Except CVS didn’t import the whole thing. I tried again: same results. It was omitting two directories from the distribution, both named core.

RTFM RTFM… Turns out that by default, CVS excludes certain filenames that it thinks don’t belong in repositories. ‘Core’ is among the blacklisted filenames, presumably because CVS is assuming that anything named ‘core’ is a UNIX core dump file. Except that these aren’t files, they’re directories. Hel-LO…!

Anyhow… here’s the command I ended up using to create the repository:

cvs import -m 'imported 2.5.2 source' -I '\!' portal/framework uPortal uPortal_rel-2-5-2

The -I ! option tells it not to ignore any filenames.

With that out of the way, onward we march to the brave new world of 2.5.x and DLM.

Pool’s open… don’t everybody jump in at once

Yesterday we finally uncovered the big concrete hole in the backyard. The water looks pretty good, but due to my neglect over the spring, I’ve got a bigger problem with surface-clinging algae than in past years. There was the usual green stuff on the bottom which easily vacuumed out, but the steps and the diagonal hopper walls have this better-established stuff that doesn’t want to come off. However, the stuff on the steps cleared right up when I flooded it with 12.5% hypochlorite from my siphon hose, so I superchlorinated yesterday evening. This morning I noticed that the areas I had brushed yesterday were clearing up, so I went ahead and brushed the entire pool (clouding it up beautifully, of course). Cl was 8.8ppm. Tonight I’ll add more, until all the muck is gone.

[More:]

Still haven’t started the coping repair project. Today (Friday) I picked up a 7″ dry-cut diamond blade for a cool $50, and I’m going to see how it does at cutting the concrete decking. It’s not big enough to cut through the entire slab, but the hope is I can make a cut around 2″ deep and then knock the rest of the piece off with a cold chisel. If it works well, I’ll go ahead and rent a larger saw to do the complete job. Whether it works or not, I’ll still end up with a nice diamond blade I can use for future projects.

The fun never ends..

6/12: The crap clinging to the diagonal hopper walls is proving to be very tenacious. It will not brush off easily in spite of repeated superchlorination. I can’t seem to get enough force on my brush to attack it effectively. I think I’m going to need a stainless steel brush for this. Before I try that, though, I’m going to try flooding the area with chlorine. It worked with the steps, so hopefully it’ll work with the hopper walls. Only problem is, I could reach the steps easily with my siphon tube, but not so with the hopper walls. So, I’m going to try a slightly different approach. I went to Home Depot and bought 20′ of food-grade tubing (1/2″ O.D.). I’ll use wire ties to attach 4′ or 5′ of hose to the bottom of my telepole, then put the pole in the water and start a siphon. I should then be able to siphon chlorine from my jug and direct the flow wherever I want. I will probably want to do this with the pool pump off, and somehow attach the tubing to the chlorine jug so I don’t inadvertently pull it out. We’ll see how it works.

6/14: Tried the above last night. It works, but it’s a little cumbersome. Attaching the siphon tube to the chlorine jug is an absolute must. I used an Irwin Quick-Grip clamp. Still, I lost my siphon and had to re-prime several times. It would also be handy to have some way to easily interrupt the flow while I move the hose to different spots. I suppose it would work to pinch the hose, or I could use a spring-loaded clamp. Still, this whole thing seems like too much hassle compared to using a steel-bristled brush, assuming the brush will work. I’ll try to get to a pool store and pick up a brush in the next couple of days.