Vores Meeho!™ Blog giver dig generelle nyheder, tekniske tips, inspiration og mere til i relation til Meeho!™-platformen.

Tilmeld dig gratis nu!

Indlæg efter forfatter

» Tidszonekonvertering med java.util.Date

Skrevet af Anders Østergaard Jensen d. 9/3 2010 kl. 06:50

Når man bygger internationale websider er det ofte nødvendigt at vise dato og tid konverteret til brugerens lokale tidszone. Ruby on Rails har indbygget understøttelse for det, mens Java altså kræver en manuel tilgang. I det følgende vil jeg vise, hvordan man nemt og bekvemt kan implementere  tidszonekonvertering i Java.

Den følgende metode foretager en tidszonekonvertering fra en standard java.util.Date (som standard er den justeret til maskinens egen tidszone) til en specifik tidszone:

public static String formatDanishDate(Date d, String tz) {
DateFormat fmt = new SimpleDateFormat(”d/MM/yyyy ‘kl.’ HH:mm Z”);
TimeZone zone = getTimeZone(tz);
fmt.setTimeZone(zone);
return fmt.format(d);
}
public static String formatUSDate(Date d, String tz) {
DateFormat fmt = new SimpleDateFormat(”EEE, d/MM/yyyy ‘at’ KK:mm a Z”);
TimeZone zone = getTimeZone(tz);
logger.error(”+++ Chosen tz was: ” + zone.getDisplayName());
fmt.setTimeZone(zone);
logger.error(”LOL FORMAT: ” + fmt.format(d));
return fmt.format(d);
}
public static String formatUSDate(Date d, String tz) {

    DateFormat fmt = new SimpleDateFormat("EEE, d/MM/yyyy 'at' KK:mm a Z");

    TimeZone zone = getTimeZone(tz);

    fmt.setTimeZone(zone);

    return fmt.format(d);

  }

Ovenstående metode er afhængig af følgende supportfunktion, som søger igennem Java-bibliotekets understøttede tidszoner (lower case-søgning). Hvis der ikke findes et resultat, returneres værdien af getDefault() blot. Ifølge Javadoc for SDK’et afhænger default-tidszonen af maskinens locale-indstillinger (hvis din maskine er indstillet til at være i København, vil default-tidszonen herefter være Europe/Copenhagen).

  public static TimeZone getTimeZone(String tz) {

    TimeZone retVal;

    for (String id: TimeZone.getAvailableIDs()) {

      if (id.toLowerCase().contains(tz.toLowerCase())) {

        retVal = TimeZone.getTimeZone(id);

        return retVal;

      }

    }

    return TimeZone.getDefault();

  }

Søgning med lowercase er særligt anvendeligt, hvis du bruger tidszoner på tværs af flere applikationer og rammeværk med den samme database. F.eks. gemmer Ruby on Rails kun den valgte tidzone med det sidste ID efter skråstregen (dvs. ‘Copenhagen’ i stedet for det mere sigende ‘Europe/Copenhagen’), hvilket gør det umuligt at implementere en en-til-en-konvertering mellem de to miljøer. Et kald til getTimeZone(”Sydney”) eller getTimeZone(”Copenhagen”) vil altså returnere Java-tidszonen “Australia/Sydney” hhv. “Europe/Copenhagen”.

Endelig muliggør klassen SimpleDateFormat visning af den nu konverterede dato-repræsentation i et lokaliseret format. Den enkelte bruger kan derfor nu også vælge, hvordan dato og tid skal repræsenteres i din applikation. Dette Javadoc-link beskriver de forskellige formatteringsmuligheder. For eksempel kan en mulig dansk repræsentation af datoen se således ud:

DateFormat fmt = new SimpleDateFormat("d/MM/yyyy 'kl.' HH:mm Z");

Fortæl os endelig, hvis du kender til andre, mere effektive metoder til at gennemføre tidszonekonvertering af dato- og tidsstempler i Java.

» Gruppemails til kontaktpersoner og kunder

Skrevet af Anders Østergaard Jensen d. 30/11 2009 kl. 03:46

Har du tit haft brug for at sende mange e-mails til flere samarbejdspartnere på én gang? Én mulighed er selvfølgelig at kopiere alle modtagerne ind i BCC-feltet fra dit mailprograms adressebog, men det bliver hurtigt uorganiseret og rodet, særligt hvis den samme liste af modtagere skal deles mellem flere medarbejdere. Og overblikket forsvinder da først fuldstændigt, når du har flere forskellige e-mail-adresser på den samme samarbejdspartner, og du ikke kan huske, hvilken der er den aktuelle.

Meeho!™ lader dig nu organisere dine gruppemails, dvs. mails der fremsendes til én eller flere grupper af kontaktpersoner eller kunder. For at sende en gruppemail til en kontaktpersongruppe skal du vælge Kunder > Kontaktpersonoversigt. Derefter klikker du på den blå pil til højre og vælger Kontaktpersongrupper:

Her kommer man ind på Kontaktpersongrupper (når man vil sende en gruppemail til alle medlemmerne af en kontaktpersongruppe).

Her kommer man ind på Kontaktpersongrupper (når man vil sende en gruppemail til alle medlemmerne af en kontaktpersongruppe).

Ligeledes finder du dine kundegrupper ved at vælge Kundeoversigt og derefter Kundegrupper. Vælger du enten en kunde- eller kontaktpersongruppe, får du nu et panel frem, hvorfra du kan sende en gruppemail til alle kontaktpersoner eller kunder i gruppen:

Her ses muligheden for at sende en gruppemail under en gruppe af kontaktpersoner.

Her ses muligheden for at sende en gruppemail under en gruppe af kontaktpersoner.

Det er helt bevidst, at Meeho!™ genererer en lidt kryptisk e-mail-adresse som modtager af din mail. Vi anvender en krypteret (scramblet) adresse netop for din sikkerhed, så eventuelle udefrakommende brugere ikke kan gætte på gruppemail-adressen til dine kunder. På den måde undgår du spam og andre ubehageligheder. Her sender vi nu endelig en mail til den valgte kontaktpersongruppe:

Sådan her kan det se ud i Gmail.

Sådan her kan det se ud i Gmail.

Listerne med gruppemails er åbne for de inkluderede kontaktpersoner eller kunder, således at de kan besvare dine e-mails direkte. Du skal her være opmærksom på, at eventuelle svar bliver videresendt til alle kontaktpersoner eller kunder på listen.

Alt i alt har vi nu introduceret et centralt gruppemail-arkiv, som konstant er tilgængeligt og opdateret – uanset hvor i verden du er. Vi håber, at den nye gruppemail-funktionalitet kan lette og effektivisere vores kunders kommunikation med deres kunder og samarbejdspartnere.

» Simpel backup med rsync

Skrevet af Anders Østergaard Jensen d. 12/11 2009 kl. 12:16

Sikre, troværdige og effektive backupstrategier er et kendt problem i enhver systemadministrators hverdag. Her hos Meeho! ApS gør vi naturligvis alt for at sikre vores kunders data så godt som overhovedet muligt. I den daglige backup anvender vi blandt andet rsync, som er et rigtig effektivt, sikkert og velafprøvet værktøj til at tage inkrementel backup. I det følgende indlæg vil jeg vise, hvordan du hurtigt kan anvende rsync til at overtage eller supplere din eksisterende backup.

rsync kan meget mere end blot at tage backup, men i vores tilfælde ønsker vi selvfølgelig at flytte vores data fra én server (kaldet source) til en anden server (target). I transportlaget anvender vi SSH (Secure Shell), så alle data overflyttes i krypteret form. På source opretter du en nøgle (som root) og skriver nøglen til et separat bibliotek, så det ikke interfererer med eventuelle eksisterende SSH-nøgler. De følgende eksempler kræver, at SSH, rsync og lignende UNIX-værktøjer er installeret i forvejen. I det følgende eksempel laver vi en SSH-nøgle, der indeholder et tomt password:

sudo ssh-keygen -f /backup/ssh_key -t rsa -N ''

Det opretter en ny RSA-nøgle til SSH i biblioteket /backup med en tilhørende offentlig nøgle:

source:[aj] % ls
ssh_key      ssh_key.pub

Derefter kopierer du filen over på serveren (f.eks. med scp) og kopierer indholdet til SSH’s authorized_keys-fil, således at backupbrugeren nu kan logge på automatisk, men krypteret:

scp ssh_key.pub backup@target:/home/backup
ssh target -l backup

(Hvor backup selvfølgelig er din backupbruger.) Og endelig laver vi et append til filen:

cat /home/backup/ssh_key.pub >> /home/backup/.ssh/auhorized_keys

Lav nu et bibliotek (på target), der skal indeholde backup’en fra source:

mkdir /home/backup/backup-source

På source kører du nu følgende rsync-kommando, der laver en fuldstændig spejling af det pågældende bibliotek og “incremental forever” (dvs. en løbende, inkrementel backup af modificerede filer mellem de to biblioteker):

/usr/local/bin/rsync -avz --delete -e "ssh -i /backup/ssh_key"
"/backup" backup@target:/home/backup/backup-source

Hvor /usr/local/bin/rsync naturligvis skal tilrettes alt efter, hvor du har placeret rsync (ovenstående sti er standard for FreeBSD). Biblioteket, der synkroniseres, er i øvrigt /backup (markeret med fed), og det skal du selvfølgelig ændre efter behov. Synkroniseringen er rekursiv, så alle underbiblioteker bliver flyttet med. Bemærk, at switchen –delete sletter filer i target, hvis det er slettet fra source. Hvis du til gengæld undlader –delete, vil intet blive slettet ved synkronisering.

For at automatisere ovenstående, kan man meget passende lægge det i et shell script (med en rsync-kommando for hvert script), og endelig kalde pågældende shell script fra cron én gang i døgnet (afhængigt af behov), men det ligger uden for omfanget af denne artikel.

Jeg håber, at det her har givet lidt inspiration til, hvordan man relativt hurtigt kan få en højtydende, effektiv og sikker backupprocedure op at køre med FreeBSD og rsync. Algoritmen er utroligt effektiv og minimerer både overførselstid og båndbreddeforbrug på en snedig vis.

NB: Husk, at tomme SSH-nøgler naturligvis udgør en vis sikkerhedsrisiko, og at dette bør anvendes med fuldstændig omtanke og beskyttelse af private keys, VPN og firewalls. Meeho! ApS fraskriver sig i øvrigt alt ansvar for eventuelle sikkerhedsbrister eller tab af data, som ovenstående artikel måtte medføre.

» JBoss 5 rc-scripts til FreeBSD

Skrevet af Anders Østergaard Jensen d. 15/10 2009 kl. 00:31

Meeho!™ er udviklet og driftet på FreeBSD, der er en UNIX-variant kendt for sin stabilitet og glimrende performance. FreeBSD UNIX betragtes den dag i dag som Internettets egentlige backbone og er fortsat det foretrukne styresystem for internetudbydere. FreeBSD har i hvert fald sikret at Meeho!™ ind til videre har en ubeklageligt pæn oppetid.

Dele af Meeho!™ er udviklet i Java og kører derfor i en Java EE-applikationsserver: JBoss. Nok er JBoss understøttet i FreeBSDs ports, men pakken er oftest nogle versionsnumre bagud. Hvis du har brug for at være cutting/bleeding edge på FreeBSD, er der dog en anden mulighed: manuel installation og deployment med et rc-script, så FreeBSD kan daemonize JBoss som en hvilken som helst anden UNIX daemon.

Hvordan gør man så det? FreeBSD er jo ikke officielt understøttet af JBoss, men efter at have hacket rundt med JBoss’ init-scripts til Red Hat Linux, fandt jeg endelig en holdbar løsning. Kopiér nedenstående scripts ind i de anviste stier og tilret eventuelle paths i scriptet. Du kan nu starte JBoss 5.x med:

/usr/local/etc/rc.d/jboss5 start

Indholdet er da:

#!/bin/sh
# PROVIDE: jboss5
# REQUIRE: LOGIN
# KEYWORD: shutdown
. /etc/rc.subr
name='jboss5'
rcvar=`set_rcvar`
load_rc_config $name
start_cmd="jboss5_start"
stop_cmd="jboss5_stop"
jboss5_start()
{
  /usr/local/jboss/bin/jboss_init_freebsd.sh start
}
jboss5_stop()
{
  /usr/local/jboss/bin/jboss_init_freebsd.sh stop
}
run_rc_command $1

Derpå kopierer du flg. indhold ind i /usr/local/jboss/bin/jboss_init_freebsd.sh:

#!/bin/sh
# This script was originally written for Red Hat Linux.
# I ported this script to FreeBSD, since the JBoss bootstrap infrastructure
# in FreeBSD Ports is broken.
# (C) Anders Oestergaard Jensen, <aj@meeho.dk> 2008
# Move this script to /usr/local/jboss/bin and start it with jboss5 start
# from /usr/local/etc/rc.d/
# Also remember to set the correct user in this script (jboss?).
#
# $Id: jboss_init_redhat.sh 60995 2007-02-28 11:35:31Z dimitris@jboss.org $
#
# JBoss Control Script
#
# To use this script run it as root - it will switch to the specified user
#
# Here is a little (and extremely primitive) startup/shutdown script
# for RedHat systems. It assumes that JBoss lives in /usr/local/jboss,
# it's run by user 'jboss' and JDK binaries are in /usr/local/jdk/bin.
# All this can be changed in the script itself.
#
# Either modify this script for your requirements or just ensure that
# the following variables are set correctly before calling the script.
# define where jboss is - this is the directory containing directories
# log, bin, conf etc
JBOSS_HOME=${JBOSS_HOME:-"/usr/local/jboss"}
# define the user under which jboss will run, or use 'RUNASIS' to run
# as the current user
JBOSS_USER=${JBOSS_USER:-"jboss"} # Set the user here!!!
#make sure java is in your path
JAVAPTH=${JAVAPTH:-"/usr/local/bin"}
#configuration to use, usually one of 'minimal', 'default', 'all'
JBOSS_CONF=${JBOSS_CONF:-"default"}
#if JBOSS_HOST specified, use -b to bind jboss services to that address
JBOSS_BIND_ADDR=${JBOSS_HOST:+"-b $JBOSS_HOST"}
#define the classpath for the shutdown class
JBOSSCP=${JBOSSCP:-"$JBOSS_HOME/bin/shutdown.jar:$JBOSS_HOME/client/jnet.jar"}
#define the script to use to start jboss
JBOSSSH=${JBOSSSH:-"$JBOSS_HOME/bin/run.sh -c $JBOSS_CONF $JBOSS_BIND_ADDR"}
if [ "$JBOSS_USER" = "RUNASIS" ]; then
  SUBIT=""
else
  SUBIT="su - $JBOSS_USER -c "
fi
if [ -n "$JBOSS_CONSOLE" -a ! -d "$JBOSS_CONSOLE" ]; then
  # ensure the file exists
  touch $JBOSS_CONSOLE
  if [ ! -z "$SUBIT" ]; then
    chown $JBOSS_USER $JBOSS_CONSOLE
  fi
fi
if [ -n "$JBOSS_CONSOLE" -a ! -f "$JBOSS_CONSOLE" ]; then
  echo "WARNING: location for saving console log invalid: $JBOSS_CONSOLE"
   echo "WARNING: ignoring it and using /dev/null"
  JBOSS_CONSOLE="/dev/null"
fi
#define what will be done with the console log
JBOSS_CONSOLE=${JBOSS_CONSOLE:-"/dev/null"}
JBOSS_CMD_START="cd $JBOSS_HOME/bin; $JBOSSSH"
JBOSS_CMD_STOP=${JBOSS_CMD_STOP:-"java -classpath $JBOSSCP org.jboss.Shutdown --shutdown"}
if [ -z "`echo $PATH | grep $JAVAPTH`" ]; then
  export PATH=$PATH:$JAVAPTH
fi
if [ ! -d "$JBOSS_HOME" ]; then
  echo JBOSS_HOME does not exist as a valid directory : $JBOSS_HOME
  exit 1
fi
echo JBOSS_CMD_START = $JBOSS_CMD_START
case "$1" in
start)
    cd $JBOSS_HOME/bin
    if [ -z "$SUBIT" ]; then
        eval $JBOSS_CMD_START >${JBOSS_CONSOLE} 2>&1 &
    else
        $SUBIT "$JBOSS_CMD_START >${JBOSS_CONSOLE} 2>&1 &"
    fi
    ;;
stop)
    if [ -z "$SUBIT" ]; then
        $JBOSS_CMD_STOP
    else
        $SUBIT "$JBOSS_CMD_STOP"
    fi
    ;;
restart)
    $0 stop
    $0 start
    ;;
*)
    echo "usage: $0 (start|stop|restart|help)"
esac

JBoss på FreeBSD kører ubeklageligt, så snart forarbejdet er gjort ordentligt. Hvis du har nogle gode erfaringer fra udvikling eller drift med Java og JBoss på FreeBSD, så hører vi meget gerne fra dig her på bloggen.