MoSKitoAnleitungJava5 Min. Lesezeit

Der vollständige MoSKito-Integrationsleitfaden – Schritt 2 – Counter hinzufügen

Schritt 2 des MoSKito-Integrationsleitfadens ergänzt den BurgerShop um Business-Counter: Bestellungen zählen mit @Count, Zutaten zählen mit @CountByParameter und Counter in Kategorien gruppieren.

Im vorherigen Beitrag haben wir die grundlegende Integration von MoSKito in das Zielprojekt durchgeführt.
Im heutigen (eher kurzen) Schritt fügen wir mit einem Counter einige geschäftsrelevante Informationen hinzu.

Counter sind eine großartige Möglichkeit, Dinge zu zählen.
Nun, so viel Weisheit gleich zu Beginn des Beitrags haben Sie vermutlich nicht erwartet, also versuche ich es anders zu formulieren.

Counter eignen sich gut, um weniger technische Producer zu zählen oder zu überwachen.

Ein typischer Monitored-Producer erzeugt Statistiken wie Request-Dauer oder durchschnittliche Fehleranzahl. Diese eignen sich hervorragend, um einen Webservice zu überwachen.
Was aber, wenn Sie einfach die Bestellungen in Ihrem Webshop zählen wollen? Dann interessieren Sie sich weder für die durchschnittliche Dauer noch für die Fehleranzahl, weil Sie diese technischen Informationen nicht haben oder nicht brauchen. Stattdessen haben Sie den Burger-Bestellzähler.

Genau das machen wir heute – wir zählen die Burger, die wir verkaufen.

Da wir im letzten Schritt die AOP-Integration verwendet haben, nutzen wir sie auch für Counter. Es gibt einen ausführlichen Beitrag über Counter in diesem Blog, dort finden Sie weitere Informationen. Um einen Counter im AOP-Stil hinzuzufügen, brauchen wir eine Klasse, die, nun ja, einfach eine Methode hat, die wir aufrufen können.

I. Einen Counter hinzufügen

Fügen wir also jetzt den Counter hinzu:

package de.zaunberg.burgershop.service;

import net.anotheria.moskito.aop.annotation.Count;

@Count
public class OrderCounter {
    public void orderPlaced(){}

}

Das ist alles: eine mit @Count annotierte Klasse und eine Methode zum Aufrufen. Jeder Aufruf einer beliebigen Methode der Klasse wird gezählt.

Jetzt müssen wir das eigentliche Zählen einbauen. In ShopServiceImpl wird eine Bestellung tatsächlich erzeugt. Daher ist dies auch ein guter Ort, um Bestellungen zu zählen.

Um eine Bestellung zu zählen, brauchen wir eine Instanz des Counters und einen Aufruf der Methode orderPlaced. Fügen wir beides hinzu.

Zuerst brauchen wir eine Variable, die wir aufrufen können:

@Monitor
public class ShopServiceImpl implements ShopService {
  private LinkedList<ShopableItem> items;
  private static Logger log = LoggerFactory.getLogger(ShopServiceImpl.class);
  //add the counter. 
  private OrderCounter counter = new OrderCounter();
...

und nun den Aufruf selbst:

@Override
public Order placeOrder(String... items) {
  ...
  counter.orderPlaced();
  return order;
}

Bauen wir den Shop nun mit mvn install und sehen wir uns an, was wir erreicht haben.

Klicken Sie auf den folgenden Link, um eine fertige Bestellung aufzugeben (Sie können die Bestellung aber auch ganz normal aufgeben):

http://localhost:8080/burgershop/order.html?choice1=wheat&choice2=pork&choice3=cheese

Damit wird eine neue Bestellung angelegt. Wenn wir jetzt einen Blick in unsere MoSKito-WebUI werfen (http://localhost:8080/burgershop/mui/mskShowAllProducers), sehen wir, dass wir einen neuen Producer namens OrderCounter im Decorator Counter haben:

Wenn wir darauf klicken:

sehen wir, dass 1 Bestellung aufgegeben wurde.

Wenn wir der Counter-Klasse weitere Methoden hinzufügen, können wir andere Geschäftswerte überwachen, etwa userRegistered, userLoggedIn, paymentReceived und so weiter. Und das alles einfach durch den Aufruf einer Methode in einer annotierten Klasse!

II. Zählen nach Parameter

Counter können aber noch mehr. Nehmen wir an, wir müssen die Zutaten unserer Burger überwachen und wissen, wie viel wir von welcher Zutat verkaufen, damit wir nachbestellen können.

Dazu fügen wir unserem Projekt eine weitere Counter-Klasse hinzu, den IngredientCounter:

package de.zaunberg.burgershop.service;

import net.anotheria.moskito.aop.annotation.CountByParameter;

public class IngredientCounter {
  @CountByParameter public void ingredientUsed(String ingredient){

  }
}

Ihnen sind sicher die 2 Unterschiede zum vorherigen Counter aufgefallen:

1. Wir haben nicht die Klasse annotiert, sondern nur die Methode.
2. Wir haben @CountByParameter statt @Count verwendet.

Da wir mehrere Zutaten haben, wäre die Standard-Annotation @Count nicht sehr praktisch, weil wir für jede Zutat eine eigene Methode hinzufügen müssten. Das sähe überhaupt nicht elegant aus.
@Count verwendet den Namen der aufgerufenen Methode als Use-Case-Namen (Stat-Namen). @CountByParameter verwendet stattdessen den ersten Parameter der Methode. Das ist deutlich praktischer, wenn die Stat-Namen Variablen sind, die wir beim Erstellen der Anwendung noch nicht kennen.

Nun fügen wir ShopServiceImpl einen neuen Counter hinzu:

@Monitor
public class ShopServiceImpl implements ShopService {

  ...
  private OrderCounter counter = new OrderCounter();
  private IngredientCounter ingredientCounter = new IngredientCounter();

  @Override
  public Order placeOrder(String... items) {
    ...
    Order order = new Order();
    for (String item : items){
      order.addItem(findItemByName(item));
      ingredientCounter.ingredientUsed(item);
    }

    counter.orderPlaced();

    return order;
  }
  ...
}

Bauen wir erneut, starten neu und geben eine Bestellung auf.

Jetzt sehen wir im Bereich des Counter-Decorators zwei Counter:

Wir sehen außerdem, dass der Zutaten-Counter nach einer aufgegebenen Bestellung 3 Treffer hat. Das ist logisch, denn unser Burger besteht aus drei Zutaten. Finden wir heraus, aus welchen:

Offenbar habe ich also einen Burger mit Weizenbrötchen, Schweinefleisch und extra Käse bestellt. Ziemlich gewöhnlich, keine Kakerlaken oder andere Leckereien.

III. Gruppen bilden

Zum Schluss ergänzen wir unsere Counter um einige Metadaten.

Da beide Geschäftswerte zählen, ordnen wir sie der Kategorie business zu, in der wir später alle geschäftsbezogenen Producer finden. Dazu übergeben wir der Annotation @Count einen zusätzlichen Parameter.

@Count (category = "business", producerId = "orders")
public class OrderCounter {

Wie Sie sehen, haben wir dem Counter auch einen kürzeren Namen gegeben. @CountByParameter verhält sich etwas anders, weil der Methodenname (zumindest vorerst) ein Pflichtbestandteil der Producer-ID ist, um mehrere Producer voneinander zu unterscheiden. Benennen wir also den Counter und die Methode um, damit die WebUI übersichtlicher wird.

@CountByParameter(category = "business", producerId="ingredients")
public void used(String ingredient){

Jetzt hat die WebUI eine Kategorie business, die (nachdem wir eine weitere Bestellung aufgegeben haben) von außen per Link aufrufbar ist: http://localhost:8080/burgershop/mui/mskShowProducersByCategory?pCategory=business

… und auch die Zutatenansicht ist übersichtlicher:

Natürlich können Sie Countern auch Accumulators und Thresholds hinzufügen und diese Werte so über die Zeit überwachen.

Das war es für heute. Im nächsten Schritt geht es darum, eigene Stats hinzuzufügen, die nicht zum Standardumfang von MoSKito gehören.

Viel Spaß und bis bald!

Haben Sie ein System, das Sie ausbremst, oder eine Idee, die bisher niemand günstig genug bauen konnte?

Lassen Sie uns reden. 30 Minuten, ohne Pitch-Deck.

Worum geht es?