Verbindungsaufbau zur Plentymarkets SOAP Api Version 110 mit Java

Das folgende Beispiel zeigt die Verwendung der Plentymarkets SOAP Api Version 110. Die SOAP-Klassen wurden mittels dem in Eclipse eingebauten Tool zur Erstellung von Java-Klassen anhand einer WSDL-Datei generiert.

public class PlentyConnector {
	private Logger logger = Logger.getLogger(PlentyConnector.class);
	private String TOKEN = "";
	private int USERID = -1;
	private PlentySoapApiFunctionContainerServiceStub service = null;

// die weiteren Methoden werden separat gezeigt

}

In der folgenden Methoden wird ein Token geladen, sofern dies noch nicht geschehen ist.

   private void createService(String accountUser, String accountPassword, String portAddress) throws Exception {
		try {
			service = new PlentySoapApiFunctionContainerServiceStub(portAddress);
			if (this.TOKEN.equals("") || USERID == -1) {
                                //request a new token
				GetAuthentificationToken req = new GetAuthentificationToken();
				req.setOLogin(new PlentySoapRequest_GetAuthentificationToken());
				req.getOLogin().setUsername(accountUser);
				req.getOLogin().setUserpass(accountPassword);
				GetAuthentificationTokenResponse resp = service.getAuthentificationToken(req);
				this.TOKEN = resp.get_return().getToken();
				this.USERID = resp.get_return().getUserID();
			}
                        //modify the service and set the userid and token as a header element
			SOAPFactory factory = OMAbstractFactory.getSOAP12Factory();
		    SOAPHeaderBlock header = factory.createSOAPHeaderBlock("verifyingToken", null);
		    OMFactory omFactory = OMAbstractFactory.getOMFactory();
		    OMNode userNameNode = omFactory.createOMElement(new QName("UserID"));
		    ((OMElement) userNameNode).setText(""+USERID);
		    header.addChild(userNameNode);
		    OMNode passwordNode = omFactory.createOMElement(new QName("Token"));
		    ((OMElement) passwordNode).setText(TOKEN);
		    header.addChild(passwordNode);
		    service._getServiceClient().addHeader(header);
			System.out.println("token: " + this.TOKEN + " userid: " + this.USERID);
		}
		catch(Exception e) {
			logger.error("Authentification token not loaded correctly!");
			throw e;
		}
	}

Die nächste Methode zeigt am Beispiel der Serverzeit, wie weitere Aufrufe erfolgen können:

	private void getServerTime() {
		try {
	    	PlentySoapResponse_GetServerTime resp = service.getServerTime(new GetServerTime()).get_return();
	    	System.out.println("Servertime : "+resp.getTimestamp());
	   }   
	   catch(Exception e) {
		   logger.error("Server time not loaded correctly: " + e.getMessage(), e);
	   }
	}

In der nachfolgenden Methode wird ein Aufruf mit ein paar Testdaten durchgeführt, um die Funktionsweise zu veranschaulichen:

	public void executePlentyCall() throws Exception {
		System.out.println("login");
		createService("MyUserName", "MyPassword", "http://my.plenty.installation.de/soap/version110/");
		getServerTime();
}

Die SOAP-Klassen zum Verbindungsaufbau wurden mit Hilfe des axis2-Tools wsdl2java.bat erstellt.

Das Duplo-Baustein-Spiel um Scrum spielerisch zu lernen und zu erleben

Scrum spielerisch erlernen

Um Scrum spielerisch zu erlernen und zu erleben, bieten sich eine Reihe von Methoden an, die unterschiedliche Ziele verfolgen. Besonders im Hinblick auf die Einarbeitung von neuen Mitarbeitern, die ggf. selbst nicht mit Scrum arbeiten, aber im Kontakt mit den Scrum-Teams stehen werden (z.B. ein neuer Mitarbeiter in der Marketing-Abteilung), bietet sich die Duplo-Bausteinen-Variante an, um einen schnellen Überblick über Scrum zu geben.
Dabei wird zunächst in kurzen Sätzen erklärt, um was es in Scrum geht, wieso Scrum im Unternehmen eingesetzt wird und was die Ziele von Scrum im Unternehmen sind. Bei vielen Teilnehmern, werden mehrere Gruppen gebildet, so dass eine Gruppe aus ca. 5 Personen besteht. Die Gruppen bekommen diverse Aufgaben gestellt, die mit Hilfe von Duplo-Bausteinen zu bewältigen sind. Der Moderator kann die Rolle des Product Owners oder die des Kunden einnehmen und liefert bei Fragen zur Umsetzung Hinweise. Jede Gruppe stellt einen Scrum Master und ggf. einen Product Owner (sofern diese Rolle nicht durch den Moderator eingenommen wird), die für das Beseitigen von Hindernissen und das Beschaffen von Informationen zuständig sind. Die einzelnen Rollen in Scrum müssen den Teams nicht bekannt sein. Die Aufgaben von Team, Scrum Master und Product Owner müssen dann allerdings vorm Start der Umsetzung beschrieben werden.

Die Aufgabe

Die Aufgaben, die die Teams erhalten, enthalten zum Teil nicht alle Informationen oder können mit den zur Verfügung gestellten Duplo-Bausteinen nicht gelöst werden. Der Moderator beobachtet das Verhalten der Teams während der Umsetzung und diskutiert anschließend die Herangehensweise zur Umsetzung der jeweiligen Aufgaben. Dabei soll zum einen vermittelt werden, dass die Kommunikation im Team wichtig ist, um eine Aufgabe gemeinsam zu lösen. Zum anderen soll diese Form des spielerischen Erlebens von Scrum dazu beitragen, dass die Beteiligten verstehen, dass nur klare Absprachen und die Kommunikation über Abteilungsgrenzen hinweg zum Ziel führen.

Spieldauer

Die Spieldauer sollte abhängig von den gestellten Aufgaben, der Firmenkultur (ist „spielen“ gern gesehen?) und der Teilnehmermenge gewählt werden. Eine mögliche Zeiteinteilung ist:

  • 15 Minuten Erklärungen zu Scrum im Unternehmen zum Ablauf und zu den Rollen
  • 20 Minuten Spiel-Durchführung
  • 10 Minuten Diskussion um Sinn und Zweck des Spiels oder zur Retrospektive

Aufgabenbeispiel

Eine mögliche Aufgabe ist das Bauen einer Garage. Je nachdem, welches Ziel mit der Aufgabe verfolgt wird, können beliebig viele Informationen fehlen, um die Teilnehmer auf eine falsche Fährte zu führen. So kann zum Beispiel eine Garage für das Unterstellen des Sportflugzeuges gewünscht sein. Die Teilnehmer werden beim Wort Garage sicherlich an eine Garage für Autos denken und diesen Punkt erst gar nicht nachragen…



Die Bausteine können z.B. im Lego Shop Deutschland erworben werden.

Auslesen einer HTML-Tabelle mit JavaScript und Auswertung von Input-Feldern

Das folgende Beispiel zeigt, wie mit Hilfe von JavaScript-Bordmitteln eine HTML-Tabelle durchlaufen werden kann. Anhand des Beispiels soll darüber hinaus eine Möglichkeit gezeigt werden, Input-Felder in den Tabellen-Zeilen auszulesen und auszuwerten.

Aufbau der HTML-Tabelle

<table id="table_example">
      <tbody>
        <tr>
          <th>Ausgewählt</th>
          <th>Bezeichnung</th>
          <th>Wert 1</th>
          <th>Wert 2</th>
        </tr>
        <tr>
          <td><input name="activated" type="checkbox" checked=""></td>
          <td>Tabellen-Inhalt erste Zeile</td>
          <td><input name="input1" class="form-control" onchange="parse_int_value(this);" style="text-align:right;" type="text" value="2"></td>
          <td><input name="input2" class="form-control" onchange="parse_int_value(this);" style="text-align:right;" type="text" value="1"></td>
        </tr>
        <tr>
          <td><input name="activated" type="checkbox" checked=""></td>
          <td>Tabellen-Inhalt zweite Zeile</td>
          <td><input name="input1" class="form-control" onchange="parse_int_value(this);" style="text-align:right;" type="text" value="2"></td>
          <td><input name="input2" class="form-control" onchange="parse_int_value(this);" style="text-align:right;" type="text" value="1"></td>
        </tr>
      </tbody>
    </table>

In der Tabelle gibt es in jeder Zeile eine Checkbox und zwei Eingabefelder. Eine JavaScript-Funktion soll nun die einzelnen Zeilen durchlaufen und auswerten, ob die Zeile markiert wurde und welche Werte eingetragen sind. Bei den Eingabefeldern sollen nur Integer-Werte erlaubt sein, weshalb der eingegebene Inhalt zunächst überprüft wird.

JavaScript zum Parsen der Input-Inhalte

function parse_int_value(ctrl) {
  ctrl.value = parseInt(ctrl.value) || 0;
}

Das Parsen der Eingabewerte erfolgt beim Durchlaufen der Tabelle erneut.

JavaScript zum Durchlaufen der Tabelle

    function parse() {
     var tblOutputDiv = document.getElementById('tbl_values');
     tblOutputDiv.innerHTML = "";
     var table = document.getElementById('table_example');
     var tmp = "";
	 	 for (var i = 1, row; row = table.rows[i]; i++) {
			//iterate through rows and check whether the row has been selected
			var checked = false;
			var value1 = 0;
			var value2 = 0;
			var inputFields = new Array();
      //get all input fields in the current row
			inputFields = row.getElementsByTagName("INPUT");
			for (var counter = 0, field; field = inputFields[counter]; counter++) {
				if (field.name == "activated") {
					checked = field.checked;
				}
				else if (field.name == "input1") {
					value1 = parseInt(field.value) || 0;
				}
				else if (field.name == "input2") {
					value2 = parseInt(field.value) || 0;
				}
			}
      tmp += 'Ausgewählt: ' + (checked ? "ja" : "nein");
      tmp += ' Wert 1: ' + value1;
      tmp += ' Wert 2: ' + value2;
      tmp += '<br/>';
		}
    tblOutputDiv.innerHTML = tmp;
    }

Zunächst wird das DIV geladen welches zur Ausgabe dient und dessen Inhalt überschrieben. Anschließend erfolgt eine Iteration durch die Zeilen der Tabelle und in jeder Zeile werden die darin enthaltenen Input-Elemente geladen. Diese werden ebenfalls durchlaufen und anhand des Namens werden die Werte in einer temporären Variable zwischengespeichert und später in dem Ausgaben-DIV ausgegeben.

Aufgerufen wird das Skript durch einen Link Tabelle auslesen.

Dieses Beispiel ist bewusst simpel gehalten und soll lediglich das Grundprinzip verdeutlichen. Das gezeigte Beispiel kann hier heruntergeladen bzw. getestet werden: HTML-Tabelle auslesen

Aufwandsschätzung mit Story Points

Verwendung von Story Points zur Aufwandsschätzung

In der agilen Softwareentwicklung werden oftmals sog. Story Points eingesetzt, um eine Aufwandsschätzung durchzuführen. Dabei wird zumeist nicht der Aufwand in Personentage zum Erledigen geschätzt, sondern die Komplexität einer Aufgabe. Die Definition der Komplexität wird dabei vom Team erarbeitet und definiert.

In der Regel sind hohe Schätzwerte ein Indiz dafür, dass die aktuellen Informationen nicht ausreichen, um eine konkrete Schätzung abgeben zu können. Ggf. muss in einem solchen Fall der Product Owner mehr Informationen und Anforderungen liefern oder das Team muss die Story in besser schätzbare Teile auseinander brechen.

Erstellen eines Wertebereiches

Als Wertebereich wird zumeist die Fibonacci-Reihenfolge bis 13, ergänzt mit 20, 40 und 100, verwendet. Zur Verdeutlichung der Bedeutung eines Wertes, kann eine Wertetabelle erstellt werden. Ein Beispiel stellt die folgende Tabelle dar:

Wert Bedeutung Beschreibung
0 Bereits erledigt
1 Sehr klein Aufgabe mit niedriger Komplexität
2 Klein Doppelt so große Komplexität wie eine sehr kleine Aufgabe
3 Mittel Entspricht einer sehr kleinen und kleinen Aufgabe
5 Mittelgroß Komplexität entspricht bereits einer mittleren Aufgabe und einer kleinen Aufgabe
8 Groß Komplexität entspricht einer mittelgroßen und einer mittleren Aufgabe
13 Sehr groß Komplexität entspricht einer großen und einer mittelgroßen Aufgabe
20 Riesig Ca. so groß wie eine große und eine sehr große Aufgabe zusammen
40 Gigantisch Kaum schätzbar, doch mindestens so groß wie zwei riesige Aufgaben
100 Unendlich Nicht schätzbar mit aktuellem Wissenstand Unfassbar!

Der Vorteil von Story Points

Die Verwendung von Story Points hat den Vorteil, dass anhand einer Schätzung nicht auf Anhieb der Aufwand abgeleitet werden kann. Schätzungen sind somit weiterhin das, was sie sind: eine vage Ausgabe über die Komplexität, basierend auf einer Schätzung. Ein weiterer Vorteil ist, dass Schätzungen basierend auf Story Points nicht verwendet werden können, um die Performance von Team-Mitgliedern oder Teams miteinander vergleichen zu können. Jedes Team erstellt für sich selbst eine eigene Wertetabelle der Schätzpunkte und findet ein für sich passendes System, um Aufgaben zu schätzen. Daher sind Abweichungen innerhalb eines Unternehmens bisweilen unausweichlich.

Erstellen eines Wertebereichs anhand eines Beispiels

story-points-Wertetabelle-270x250@2x
Wertetabelle

Eine Methode zum Definieren einer Wertetabelle ist das Heranziehen einer Referenz-Story. Dabei einigt sich das Team zunächst auf eine Referenz-Story, die nicht zu groß und nicht zu klein ist und die von allen Team-Mitgliedern geschätzt werden kann. Aufbauend auf dieser Referenz, werden die weiteren Stories im Backlog geschätzt und in eine Relation zueinander gesetzt. Aufgaben mit vergleichbaren Schätzungen können gestapelt werden, so dass im Idealfall am Ende eine überschaubare Anzahl Stapel übrig bleibt. Eine Lösung zum Aufbau der Wertetabelle kann sein, dass der Stapel mit der niedrigsten Schätzung die Story Point-Wertung 1 erhält, der nächste Stapel die 2 usw.

Schätzung der Dauer anhand der Velocity

Um aus geschätzten Stories ableiten zu können, wie lange es in etwa dauern wird, bis sie umgesetzt worden sind, wird die Velocity herangezogen. Die Velocity ist der Durchsatz an Story Points, den das Team bisher erzielt hat (bzw. die Anzahl der Story Points, die das Team pro Sprint erledigt). Über mehrere Sprints hinweg wird festgehalten, wie viele Story Points erledigt werden konnten. Bleiben Wertetabelle, Referenz-Stories und Team-Zusammensetzung über diesen Zeitraum gleich, kann diese Velocity zur Release-Planung verwendet werden. Ein eingespieltes Team wird im Laufe eines Projektes die Velocity vermutlich steigern und folglich mehr Story Points pro Sprints als am Anfang umsetzen können. Die Schätzungen der Stories sind davon nicht betroffen und müssen nicht angepasst werden, da sie lediglich etwas über die Komplexität, aber nicht den Aufwand aussagen.

Iterationen und Sprints

Der Einsatz von Iterationen in der agilen Softwareentwicklung

In der agilen Softwareentwicklung werden Iterationen eingesetzt, um eine am Beginn der Iteration festgelegte Menge an Stories zu bewältigen. Iterationen werden oftmals als Sprints bezeichnet und deren Dauer ist Abhängig von der Team-Größe, der Komplexität der Aufgaben und der Firmenkultur. Häufig sind Sprints 2 bis 4 Wochen lang, bei kleineren Projekten ist eine Sprint-Dauer von 1 Woche üblich.

Ein Sprint dauert üblicherweise 2 Wochen

Ein Sprint beginnt mit einem Planungsmeeting, dem sog. Sprint Planning. Dieses Meeting kann unterteilt werden in Sprint Planning 1 und Sprint Planning 2. Die Stories, die in diesen Meetings besprochen werden, stammen aus dem Backlog und werden vom Product Owner präsentiert. Dieser beantwortet Fragen und nennt weitere Anforderungen. Für den eigentlichen Inhalt eines Sprints ist das Team verantwortlich.

Die folgende Abbildung zeigt den üblichen Verlauf eines Sprints:
Sprint-Zyklus-300x100

Während des Sprints findet ein tägliches Meeting statt (das sog. Daily Scrum), in dem die aktuellen Fortschritte, aufgetretene Probleme und die Pläne des aktuellen Tages besprochen werden. Am Ende eines Sprints erfolgt eine Präsentation des Erreichten (Sprint Review) und eine Retrospektive (Sprint Retrospective) wird durchgeführt. Das Ziel eines jeden Sprints ist es, einen Teil des Gesamtprojektes ausliefern zu können, um möglichst frühzeitig Feedback einholen zu können.

Das Ziel sollte sein, am Ende etwas liefern zu können