Dienstag, 27. November 2012

Jazz - der Traum

damit das auch mal wieder gesagt ist: so zu arbeiten wäre der Traum.
Aber eben - die Realität ist: unverlinkbare Word-Dokumente, Excel - etc…

Jazz Platform



Mittwoch, 21. November 2012

Erwartete Exception in JUnit

Wieder ein Klassiker, den ich jedesmal vergesse, wenn ich ihn brauche - drum hier im Blog. Ich erwarte in JUnit einen Exception, und möchte auch die Message der Exception testen. Hier ist die Lösung:
@Rule
public ExpectedException dupliziertesTargetJUnitRule = ExpectedException.none();
@Test
public void duplikateException(){
dupliziertesTargetJUnitRule.expect(PolicyException.class);
dupliziertesTargetJUnitRule.expectMessage("PolicyDuplikat1");
dupliziertesTargetJUnitRule.expectMessage("PolicyDuplikat2");
//Code, der die Exception auslöst...
Environment frameworktest= new Environment();
brokerportal.addAttribute(EnvironmentAttributeType.APPLICATION, "frameworktest");
SARERequest request = new SARERequest(arbeiter, Action.MUTATE, vertrag, frameworktest);
Decision entscheid = RPDP.doerDaeDaDaa(request);
}
Möchte man die Message nicht anschauen, erwartete bloss, dass es knallt, genügt dies:
@Test(expected=PolicyException.class)
public void duplikateException(){
//Code, der die Exception auslöst...
Environment frameworktest= new Environment();
brokerportal.addAttribute(EnvironmentAttributeType.APPLICATION, "frameworktest");
SARERequest request = new SARERequest(arbeiter, Action.MUTATE, vertrag, frameworktest);
Decision entscheid = RPDP.doerDaeDaDaa(request);
}

Donnerstag, 15. November 2012

Reflections

Um Klassen zur Laufzeit zu laden, habe ich grad folgendes kleines, sehr mächtiges Framework entdeckt:

http://code.google.com/p/reflections/


Damit lässt sich sehr einfach eine einfache Plug-In Architektur erstellen, um - in diesem Fall - zur Laufzeit Policies zu laden, die eine Policy-Klasse erweitert.

Bemerkung: wie zu erwarten war, funktioniert das natürlich - wie immer in solchen Fällen - unter JBoss nicht, wegen Klassenlader-Problemen. Wir suchen die Lösung noch...


package ch.schumm.security.pdp;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/**
* Policies mit dieser Annotation werden vom PolicyDispatcher nicht geladen und damit auch nicht ausgewertet.
* @author C709360
*
*/
@Retention(RetentionPolicy.RUNTIME)
public @interface IgnorePolicy {
}
package ch.schumm.security.pdp;
import java.lang.annotation.Annotation;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import org.reflections.Reflections;
import ch.schumm.security.policy.Policy;
public class ReflectionPolicyFinder {
/**
* Findet alle Policies im Packet ch.schumm.security.policy - ausser Policies mit der {@link IgnorePolicy}
* Annotation, z.B. die Default-Policy.
* @return
*/
public static List<Policy> scanForPolicies() {
Reflections reflections = new Reflections("ch.schumm.security.policy");
Set<Class<? extends Policy>> policyTypes = reflections.getSubTypesOf(Policy.class);
ArrayList<Policy> policiesReturn = new ArrayList<Policy>();
for (Class<? extends Policy> policyType : policyTypes) {
// if (policyType != DefaultPolicy.class) {
if (!policyHasIgnoreAnnotation(policyType)) {
try {
Policy policy = policyType.newInstance();
policiesReturn.add(policy);
System.out.println(policy);
} catch (InstantiationException e) {
throw new PolicFinderException(e);
} catch (IllegalAccessException e) {
throw new PolicFinderException(e);
}
}
}
return policiesReturn;
}
private static boolean policyHasIgnoreAnnotation(Class<? extends Policy> policyType) {
boolean hasIgnoreAnotation = false;
Annotation[] declaredAnnotations = policyType.getDeclaredAnnotations();
for (Annotation annotation : declaredAnnotations) {
if (annotation.annotationType() == IgnorePolicy.class) {
hasIgnoreAnotation = true;
}
}
return hasIgnoreAnotation;
}
public static void main(String[] args) {
scanForPolicies();
}
}

Samstag, 10. November 2012

Warum Java?!? Ich mach doch nichts. Der Facebook-Updater.

Ich habe mein "Mountain Lion" frisch installiert, noch ohne Java (neuerdings hat ein frischer Mac noch kein Java...) - und beim jeden einloggen kommt die Meldung:
Was ist das?!? Ich habe nichts mit Java gestartet. Läuft da irgendein Zeugs, das ich nicht will?!?

Ein Blick in die Console verrät mir: 
Nov 10 20:48:34 oscar.local Download Java Components[3256]: Java Install cancelled


Und, eine Prozess-ID tiefer, ein Klick früher, der Übeltäter: 
Nov 10 20:48:26 oscar com.apple.launchd.peruser.501[141] (com.facebook.videochat.rschumm.updater[3255]): Exited with code: 1


Facebook? Wtf... 
Es stellt sich heraus, dass facebook-Video-Chat, eine Abklatsch-Version von Skype, stinkfrech einen LaunchAgent installiert, der immer wieder (und auch beim Einloggen) den Befehl
java -cp /Users/rschumm/Library/Application Support/Facebook/video/1.2.0.158/FacebookUpdate.jar
laufenlässt. Gopf :-) 

Getriggert wird das durch
/Users/rschumm/Library/LaunchAgents/com.facebook.videochat.rschumm.plist



Wenn ich die Datei lösche, ist der Spuk vorbei. Und ich habe was über LaunchAgents gelernt. 
Weitere Infos: 

Wenn das alle so machen würden wie Facebook.... dann könnte man noch lange warten mit Einloggen. 

Mittwoch, 7. November 2012

TimeMachine: neue HD

Mac OS X ist schon cool…
Ich habe soeben eine neue Harddisk in mein gutes altes MacBook Pro unter «Mac OS X Mountain Lion» eingebaut. Mit dem Migrations-Assi alles von der alten HD importiert. Dauert stundenlang, aber klappt. (Man könnte das auch von TimeMachine machen.)
Nun kommt aber die grosse Frage: neue Harddisk, neue UUID der Harddisk - peilt das TimeMachine oder macht es ein volle Backup und verliert die History?

Die Antwort im system.log:


Nov  7 18:56:21 oscar.local com.apple.backupd[419]: Backing up to: /Volumes/Time Machine-Backups/Backups.backupdb
Nov  7 18:56:24 oscar.local com.apple.backupd[419]: Inherited root volume Macintosh HD, UUID: BFEA6DB7-xxxx-xxxx-xxxx-xxxxxxxxxxxxx
Nov  7 18:56:25 oscar.local com.apple.backupd[419]: Event store UUIDs don't match for volume: Macintosh HD
Nov  7 18:56:34 oscar.local com.apple.backupd[419]: Deep event scan at path:/ reason:must scan subdirs|new event db|
Nov  7 18:56:34 oscar.local com.apple.backupd[419]: First backup after disk inheritance for / - complete scan required
Nov  7 18:56:34 oscar.local SystemUIServer[180]: Warning: accessing obsolete X509Anchors.


cool… First backup after disk inheritance - die History geht also nicht verloren.

mvn release: update Versions

Um mit dem Maven Release Plug-In Versionsnummer anzupassen, ohne den ganzen anderen Karsumpel zu machen:

mvn release:update-versions -DautoVersionSubmodules=true



Details:
http://maven.apache.org/plugins/maven-release-plugin/examples/update-versions.html


Freitag, 2. November 2012

Java aus xsd: JAXB

Etwas kleines, nicht neues, einfaches, aber extrem cooles:

Man hat ein Schema, z.B. das von XACML3,
http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd
und möchte davon mit Java eine Instanz abfüllen.

Nichts einfacher als das mit JAXB:

Man stelle das Schema in /src/main/xsd und lasse einen mvn install laufen, mit folgendem Plugin konfiguriert:

<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>jaxb2-maven-plugin</artifactId>
<version>1.5</version>
<executions>
<execution>
<id>xjc</id>
<goals>
<goal>xjc</goal>
</goals>
</execution>
</executions>
</plugin>
view raw pom.xml hosted with ❤ by GitHub
import java.io.StringReader;
import java.io.StringWriter;
import javax.xml.bind.JAXB;
import oasis.names.tc.xacml._3_0.core.schema.wd_17.DecisionType;
import oasis.names.tc.xacml._3_0.core.schema.wd_17.RequestType;
import oasis.names.tc.xacml._3_0.core.schema.wd_17.ResponseType;
import oasis.names.tc.xacml._3_0.core.schema.wd_17.ResultType;
import oasis.names.tc.xacml._3_0.core.schema.wd_17.StatusType;
public class XacmlMarshallUtil {
public static Result extractResultFromXacmlResponseString(String xacmlResponseAsString) {
StringReader reader = new StringReader(xacmlResponseAsString);
ResponseType responseType = JAXB.unmarshal(reader, ResponseType.class);
ResultType resultType = responseType.getResult().get(0);
DecisionType decision = resultType.getDecision();
StatusType status = resultType.getStatus();
Result result = mapToOurResult(decision, status);
return result;
}
view raw unmarshall.java hosted with ❤ by GitHub
package com.axa.ch.authorization.client.pep.facade;
import static org.junit.Assert.assertEquals;
import java.io.IOException;
import org.junit.Test;
import org.xml.sax.SAXException;
import junit.framework.Assert;
public class XacmlMarshallUtilTest {
@Test
public void testExtractResultFromXacmlResponseString() {
Result result = XacmlMarshallUtil.extractResultFromXacmlResponseString(createResponse());
assertEquals(Result.Decision.Deny, result.getDecision());
}
private String createResponse() {
return "<?xml version=\"1.0\" encoding=\"UTF-8\"?> "
+ "<Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\">"
+ "<Result><Decision>Deny</Decision></Result></Response>";
}
}


Die generierten Klassen landen in target und werden von eclipse automatisch in den build-path genommen. Fertig. 



Die Klassen können dann ganz einfach benützt werden: hier wird z.B. ein XACML-String von JAXB geparst und in Java umgewandelt:

import java.io.StringReader;
import java.io.StringWriter;
import javax.xml.bind.JAXB;
import oasis.names.tc.xacml._3_0.core.schema.wd_17.DecisionType;
import oasis.names.tc.xacml._3_0.core.schema.wd_17.RequestType;
import oasis.names.tc.xacml._3_0.core.schema.wd_17.ResponseType;
import oasis.names.tc.xacml._3_0.core.schema.wd_17.ResultType;
import oasis.names.tc.xacml._3_0.core.schema.wd_17.StatusType;
public class XacmlMarshallUtil {
public static Result extractResultFromXacmlResponseString(String xacmlResponseAsString) {
StringReader reader = new StringReader(xacmlResponseAsString);
ResponseType responseType = JAXB.unmarshal(reader, ResponseType.class);
ResultType resultType = responseType.getResult().get(0);
DecisionType decision = resultType.getDecision();
StatusType status = resultType.getStatus();
Result result = mapToOurResult(decision, status);
return result;
}
view raw unmarshall.java hosted with ❤ by GitHub

Proxy...

Die Arbeits-Bremse in jedem Unternehmensnetzwerk: Proxy. Jedesmal muss ich nachschauen, darum hier:



System.setProperty("http.proxyHost", "myProxyServer.com");
System.setProperty("http.proxyPort", "80");
bzw: -Dhttp.proxyHost=10.0.0.100 -Dhttp.proxyPort=8800