Posts Tagged: ‘Spring Boot’

Schulungsangebot – Spring Boot & Domino: REST APIs

14. Februar 2019 Posted by Sven Hasselbach

Kurs „Spring Boot & Domino: REST APIs“

Für große Anwendungen ist eine REST Schnittstelle heutzutage unverzichtbar. Doch mit den Bordmitteln sind schnell Grenzen erreicht und auch die Einbeziehung von Entwicklern ohne Domino-Hintergrundwissen gestaltet sich schwierig

Spring Boot ist der Defacto-Standard für Unternehmensanwendungen im Java-Umfeld und eine robuste wie auch flexible Alternative zu existierenden Frameworks des Domino-Umfelds.

Der Kurs vermittelt die nötigen Kenntnisse, um eine Spring Boot-basierte REST API zu entwickeln und diese als OSGi Plugin zu deployen. Ergänzt wird der Kurs durch langjährige Praxiserfahrung im täglichen Einsatz. Themen wie Token-Authentifizierung, Caching-Strategien für Hochperformante Anwendungen, Multi-Threading-Support, automatisierte Dokumentation dank Swagger uvw. werden im Kurs ausführlich behandelt.

Als Startpunkt für eigene Entwicklungen ist der verwendete Source Code Lizenzfrei enthalten.

Dauer: 3 Tage / Preis 3.500 € zzgl. MwSt. (Unabhängig von der Teilnehmerzahl)

Zielgruppe: Anwendungsentwickler Lotus Notes / Domino. Webentwicklungs- und Java- kenntnisse vorausgesetzt.

Bei Interesse oder Fragen bitte eine Mail an mich (freelancer AT hasselba.ch) oder das Kontaktformular nutzen.

Spring Boot Admin: Einfach genial und genial einfach

14. Oktober 2018 Posted by Stephan Kopp

Spring Boot Applikationen eignen sich optimal, um eine Microservice Applikation bestehend aus vielen kleinen Applikationen zu erstellen. Doch wie überwacht und verwaltet man diese Sammlung aus einzelnen Programmen?

Das Spring Boot Admin Projekt ist hierfür eine geniale und vor allem kostenlose Ergänzung.

Spring_Boot_Admin-3.png

Spring Boot Admin Server

Als Admin Server erstellt man sich eine eigene Spring Boot Applikation, fügt die Maven Dependency und die Annotation @EnableAdminServer hinzu und das wars schon.

pom.xml

<dependency>
   <groupId>de.codecentric</groupId>
   <artifactId>spring-boot-admin-starter-server</artifactId>
</dependency>

Spring Boot Applikation

@EnableAdminServer
@SpringBootApplication
public class AdminServerApplication {

   public static void main(String[] args) {
      SpringApplication.run(AdminServerApplication.class, args);
   }
}

An diesem Server können sich jetzt alle Spring Boot Applikationen anmelden. Ein Beispiel findet man hier.


Nun zur Client Applikation, die sich am Server anmeldet

Dazu muss man lediglich das Client Paket in die Dependencies aufnehmen und zwei Parameter setzen. Das wäre die minimale Variante, aber natürlich noch längst nicht alles. Um wirklich alle Features nutzen zu können, müssen doch noch ein paar Dinge gemacht werden. Zunächst aber zu den Basics.

pom.xml

<dependency>
    <groupId>de.codecentric</groupId>
    <artifactId>spring-boot-admin-starter-client</artifactId>
    <version>2.0.3</version>
</dependency>

application.properties

spring.boot.admin.client.url=http://localhost:9090

Actuator

Dieses Paket integriert eine Menge nützlicher APIs in die eigene Applikation, welche vom Spring Boot Admin Server verwendet werden um die eigene Applikation zu überwachen und auch zu steuern.

pom.xml

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

application.properties

management.endpoints.web.exposure.include=*
logging.file=log/logfile.txt
logging.pattern.file=%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(%5p) %clr(${PID}){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n%wEx

Der Actuator funktioniert auch ohne Konfiguration, aber mit diesen Einstellungen passiert zusätzlich zu den Standards noch folgendes:

  • Es werden alle Endpoints aktiviert, nicht nur health und up
  • Es wird ein Logfile geschrieben und farblich formatiert, dadurch wird auch automatisch der Endpoint aktiviert um auf dieses Logfile zuzugreifen

Security

Security sollte von Beginn an immer aktiviert sein. Damit benötigt natürlich auch der Admin Server Zugang zu unserer Applikation, bzw. nur zur /actuator API. Das kann man z.B. durch einen eigenen zentralen User machen, oder auch mit selbst generierten Accounts pro Applikation. Diese Zugangsdaten müssen dem Admin Server bei der Anmeldung mitgeteilt werden.

pom.xml

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>

application.properties

spring.security.user.name=user
spring.security.user.password=password

spring.boot.admin.client.instance.metadata.user.name=${spring.security.user.name}
spring.boot.admin.client.instance.metadata.user.password=${spring.security.user.password}

Das wars schon

Dieses Basis Setup genügt, um ein zentrales (wirklich schönes) Webinterface zu haben, über das ich alle notwendigen Informationen meiner Applikationen abrufen kann. Es geht dabei nicht nur um den reinen Status up/down. Ich kann direkt auf die Logs der Services zugreifen oder mir die eingehende http Requests anschauen und noch sehr viel mehr.

Spring_Boot_Admin-7.png

Spring_Boot_Admin-4

Spring_Boot_Admin-5

Ein nettes Feature ist z.B. auch die Veränderung meiner Log Einstellungen ohne die Services neu starten zu müssen.

Spring_Boot_Admin-6

Jeder, der sich mit Spring Boot Applikationen beschäftigt, sollte sich das Spring Boot Admin Projekt mal genauer anschauen. Unter anderem deshalb liebe ich OpenSource.

Meinen Beispiel Code kann man sich hier anschauen.

Dropping Domino’s HTTP task (3): WebSSO Integration (Part 1)

30. Juli 2018 Posted by Sven Hasselbach

To integrate the new HTTP stack into the existing environment, we can use LTPA tokens. These tokens are cookies which store the authentication information and allow to share them betweeen different participating Domino servers. A users must log on only once, and existing applications and data/views can be accessed without a relogin.

Validating an existing LTPA token with Spring can be done with our own PreAuthentificationFilter which checks for an existing LTPA token and extracts the authentication details from the cookie and creates a new Principal instance.


import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.web.authentication.preauth.AbstractPreAuthenticatedProcessingFilter;

public class LtpaPreAuthenticatedFilter extends AbstractPreAuthenticatedProcessingFilter {

   @Value("${ltpa.secret}")
   private String ltpaSecret;

   @Value("${ltpa.cookieName}")
   private String ltpaCookieName;

   @Override
   protected Object getPreAuthenticatedPrincipal(HttpServletRequest request) {

      Cookie[] cookies = request.getCookies();
      if( cookies == null ) {
         return null;
      }

      for( int i= 0; i<cookies.length ; i++ ){
         String name = cookies[i].getName();
         String value = cookies[i].getValue();

         if( ltpaCookieName.equalsIgnoreCase(name) ){
            DominoLtpaToken ltpaToken = new DominoLtpaToken( value, ltpaSecret );

            if( ltpaToken.isValid() ){
               return ltpaToken.getDistinguishedName();
            }
         }
      }

      return null;
   }

   @Override
   protected Object getPreAuthenticatedCredentials(HttpServletRequest request) {
      // is required to return an empty string
      return "";
   }

}

The filter implements two methods, one for extraction of the principal, and the other for the credentials (which we don’t have with LTPA tokens). In the getPreAuthenticatedPrincipal method, existinig LTPA tokens are searched, then the user extracted and the token validated.

The secret of the LTPA token and the name are stored in application.properties:

The second part is implementing a AuthenticationUserDetailsService. This service is for getting additional details for the authenticated user, for example the ACL roles or groups the user belongs to.

import java.util.Collection;
import java.util.HashSet;

import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.AuthenticationUserDetailsService;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken;

public class LtpaUserDetailsService implements AuthenticationUserDetailsService<PreAuthenticatedAuthenticationToken> {

   @Override
   public UserDetails loadUserDetails(PreAuthenticatedAuthenticationToken token)
      throws UsernameNotFoundException {

      String userName=(String)token.getPrincipal();

      Collection<GrantedAuthority> authorities = new HashSet<GrantedAuthority>() ;
      authorities.add(new LtpaUserAuthority());

      User user = new User(userName,"",authorities);

      return user;
    }

}

In our case, we are just adding an LtpaUserAuthority to the user information. Don’t worry about the usage of the LtpaUserAuthority. We come back to this in another post.

import org.springframework.security.core.GrantedAuthority;

public class LtpaUserAuthority implements GrantedAuthority {

   private static final long serialVersionUID = 1L;

   @Override
   public String getAuthority() {
      return "ROLE_USER_LTPA";
   }

}

In the last step we have to update the SecurityConfig.java to activate the filter:

@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

   @Configuration
   @Order(1)
   static class DominoLtpaSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {

      @Bean
      public AuthenticationUserDetailsService<PreAuthenticatedAuthenticationToken> authenticationUserDetailsService() {
         return new LtpaUserDetailsService();
      }

      @Bean
      public PreAuthenticatedAuthenticationProvider preAuthenticatedAuthenticationProvider() {
         PreAuthenticatedAuthenticationProvider provider = new PreAuthenticatedAuthenticationProvider();

         provider.setPreAuthenticatedUserDetailsService(authenticationUserDetailsService());
         provider.setUserDetailsChecker(new AccountStatusUserDetailsChecker());

         return provider;
      }

      @Override
      protected void configure(AuthenticationManagerBuilder auth) throws Exception {
         auth.authenticationProvider(preAuthenticatedAuthenticationProvider());
      }

      @Bean
      public AbstractPreAuthenticatedProcessingFilter preAuthenticatedProcessingFilter() throws Exception {
         LtpaPreAuthenticatedFilter filter = new LtpaPreAuthenticatedFilter();
         filter.setAuthenticationManager(authenticationManager());
         return filter;
      }

      @Override
      protected void configure(HttpSecurity http) throws Exception {
         http.addFilter(preAuthenticatedProcessingFilter())
         .authorizeRequests()
         .antMatchers("/**").permitAll() ;
      }
   }
  ...
}

This includes the filter in any request. Now, the Principal contains the user name stored in the LTPA token.

Dropping Domino’s HTTP task (2): Running in User Context

17. Juli 2018 Posted by Sven Hasselbach

To use the approach as an alternative to Domino’s HTTP task, we need support for the different user contexts, because using NotesFactory.createSession() just creates a session for the current Notes ID used.

This goal can be achived by using the Java NAPI and the following method:

import com.ibm.domino.napi.NException;
import com.ibm.domino.napi.c.NotesUtil;
import com.ibm.domino.napi.c.xsp.XSPNative; 

/**
* create a new Domino session for the give username
* @param userName
* String containing the canonical username
* @return
* lotus.domino.Session for the given username
* @throws NException
* @throws ServletException
*/
public static Session createUserSession(final String userName)
{
   Session session = null;
   try {
      long hList = NotesUtil.createUserNameList(userName);
      session = XSPNative.createXPageSession(userName, hList,
         false, false);

      return session;
   } catch (Exception e) {
      e.printStackTrace();
   }

   return session;
}

It is required to load the required njnotes.dll before this method can be used, otherwise the C-API references won’t work. This must be done after initiation of the NotesThread and (only once) per thread:

System.loadLibrary("njnotes");

It is also required to use the full hierarchical name for the session creation, otherwise readers / authors won’t work correctly (you can create a session for every user you want, even for not existing ones).

To get this work correctly, I have created a little helper class which memorizes if the Notes-relevant part was already initialized for the thread used:

public class Utils {

   private static final ThreadLocal<Boolean> isNotesInitialized = new ThreadLocal<Boolean>();

   public static void initNotes(){

      // check if the Thread is already initialized
      if( Boolean.TRUE.equals( isNotesInitialized.get() ) )
         return;

      // init Notes
      NotesThread.sinitThread();
      System.loadLibrary("njnotes");

      // mark as initialized
      isNotesInitialized.set( Boolean.TRUE );

   }

}

Now let’s activate Spring Boot Security on the new server by adding the required dependencies to the pom.xml:

<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-security -->
<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-security</artifactId>
</dependency>

To use the authentication with the existing Domino environment, we can use our own AuthenticationProvider:

import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.stereotype.Component;

import org.springframework.security.authentication.BadCredentialsException;

@Component
public class CustomAuthenticationProvider implements AuthenticationProvider {

   @Override
   public Authentication authenticate(Authentication authentication) throws AuthenticationException {
      String name = authentication.getName();
      String password = authentication.getCredentials().toString();

      String realUser = validatePassword( name, password );

      if( Utils.isEmptyString( realUser ) ){
         throw new BadCredentialsException("Authentication failed for user = " + name);
      }

      return auth;
   }

   @Override
   public boolean supports(Class<?> authentication) {
      return authentication.equals(UsernamePasswordAuthenticationToken.class);
   }

   public String validatePassword( final String userName, final String password){
      // see https://github.com/hasselbach/domino-stateless-token-servlet/blob/master/src/ch/hasselba/servlet/DominoStatelessTokenServlet.java
      // and convert the username to the hierarchical one
   }
}

If the authentication was successfull, we can access the correct username from the Principal object. Just add it as a parameter to the controller method, and you get the hierarchical name.

@MessageMapping("/hello")
@SendTo("/topic/greetings")
public Greeting greeting(HelloMessage message, Principal principal) throws Exception {

   Thread.sleep(1000); // simulated delay

   // init Notes
   Utils.initNotes();

   // create the session for the user
   Session session = (Session) Utils.createUserSession(principal.getName());

   return new Greeting("Hello, " + HtmlUtils.htmlEscape( session.getEffectiveUserName() ) + "!" );
}

Now let’s see this in action:

P.S.
I have ignored recycling and termination of the Notes threads for an easier understanding.

HCL, Domino & node.js

23. Juni 2018 Posted by Sven Hasselbach

I am very happy to hear that HCL invests in Domino and improves the existing technology stack. But as a German, I have to be sceptical (it’s in our genes), because I can not see any advantage in the integration of node.js applications on top of Domino. I have written a demo two years ago, just to prove that it would be possible.

One of the main reasons is that I have switched my application architecture, which means that Domino is nothing more than a great NoSQL-Datacontainer. While the existing REST APIs were absolutly not fitting my requirements (too slow, painfull output and not expandable), I have pursued „my own way“ by using Spring Boot as my preferred technology. This made me independent from IBMs release cycles, and since the Java 8 upgrade I am happy, because I was able to add the missing parts which where never delivered by IBM.

Token authentication? Solved by creating my own solution. Performance? Boosted with Memcache. Memory limitations? Also solved with Memcache. Delay of agent execution? Solved with Spring Boot. I have dropped the Designer and using Eclipse directly, especially development/maintenance of legacy Java agents makes a lot of more fun. Code analysis / quality? Maven, JUnit & SonarQube are your friends. SSL encryption? Nginx. And the list grows and grows…

My point is that beeing independet from IBMs releases allows me to be extremly flexible – which IBM is not. Just have a look at Bootstrap and XPages: I have created my own renderers, and I can switch to the latest version with a few clicks (as long as there is no fundamental change in the structure). I am not dependent that – maybe – in the future someone will adopt the version to the XPages Extension library. If one of my customers wants to use it, OK, no problem.

That‘s what my customers love: The sky (aka budget) is the limit.

And here comes the problem I see with the node.js integration: The release cycles are extremely short. Just have a look at the release list:

https://nodejs.org/en/download/releases/

In the last 8 monthes there where 10(!) new versions for Carbon (V8, LTS). 26 versions since 2016 for Boron (V6, LTS). And that’s only node.js – the core of the whole thing. Don’t forget the packages and their dependencies. Let’s skip the fundamental problems with the NPM ecosystem: If it is required to get the latest updates, „npm update -g“ and everything is fine.

But waiting for Big Blue for a hot fix? If the „Domino NPM Package“ is not updated, but depends on an older version, you maybe cannot update the whole application. Ever had problems withthe old Jar files of the Domino JVM? Or was it required to downgrade of the Eclipse Maven Plugin to run with Domino’s JRE 6? Just think about it…

Don‘t get me wrong: This is not against the technology. I am using JavaScript for more than 15 years and have build some node.js applications and React Native apps in the last years, but I am not a fan of JavaScript because of the chaotical language concept, and the pain when trying to find syntax errors in scripting languages in general, or the missing type safety (something which is not required in compiler languages). But you can build great and high performant applications, and ES6 was a big step forward.

In my eyes there is no reason for tying node.js with Domino. My advice is to build REST interfaces on top of Domino (and reuse the existing business logic), and access it with a separate application based on [enter your preferred technologie here] with a backend connector. The frontend can be realised by a web development team / company. This takes a lot pressure off the existing Domino environment (from the management perspective): You can build new applications with the current hipster technology, can find developers and administrators, and the costs for moderinzation are not as high as a migration. After taking this path, some customers who abandoned Domino years ago, are investing again in the product.

So far I am still open for a big surprise and hopefully HCL can convince me of the contrary.

P.S.

I am still developing XPages applications, in my eyes a great technologiy, but it was never adopted by the developers as it should. With node.js, you have a new learning curve: Dojo/jQuery is NOT JavaScript.

Domino & Spring Boot: How does it work

1. Juni 2018 Posted by Sven Hasselbach

The example Spring Boot Plugin I have published two days ago is a full working example to run a Spring Boot applications directly in the Domino HTTP task. It is designed as an OSGi plugin and runs inside the servlet container, which means that the „normal“ features of the Domino HTTP task are available at runtime, for example the existing the user session is accessible via the ContextInfo object.

To complile and deploy the plugin, you first have to install the XPages SDK and create the missing feature project and update site project as described in on of my older posts.
After importing the plugin in the UpdateSite and restarting the HTTP task, the Spring Boot application is ready and will flood the console with a lot of debugging informations when the first request hits the application:

While the example is a really basic one I am using the same approach for years in production environment. The reason is that it was fundamental for the customer (which has abandoned Domino years ago) to have a modern and industry-wide standard framework: The application is now a Spring Boot application which has a NoSQL backend – the decision makers had some buzzwords, the term „Domino“ is no longer used and all participants are happy now.

How does it work?

First it is required that the main configuration is still in the web.xml file. This is required because of the old servlet container which is still only available in version 2.5; I was not successfull to implement the latest Spring Boot version 5, because it seems that a servlet container version 3.0 is required.

In the web.xml file, the servlet mapping is defined:

<servlet>
   <servlet-name>dominoSpringBootServlet</servlet-name>
   <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
   <load-on-startup>1</load-on-startup>
</servlet>

An additional configuration file dominoSpringBootServlet.xml contains the servlet specific configuration; both (the servlet name and the XML configuration) must have the same name, otherwise Spring Boot will not find the configuration file.

In this configuration file, the base package is defined, which tells the framework where to scan for Java classes and annotations:

<context:component-scan base-package="domino.springboot.plugin" />

The following line enables Spring Boot’s annotations:

<mvc:annotation-driven />

Now, the package domino.springboot is scanned for controllers and configuration classes, which I will describe in the next post.

 

Domino & Spring Boot: An example project

30. Mai 2018 Posted by Sven Hasselbach

I have uploaded an example for running Spring Boot applications on top of Domino. You can find it here:
https://github.com/hasselbach/domino-springboot

This solution is running for years in productive environments.

Hopefully I will find some time to explain how it works.

Domino & Spring Boot: ScheduledTasks

2. Mai 2018 Posted by Sven Hasselbach

When developing Spring Boot applications running on Domino, there is a feature which runs out of the box and makes developers happy: ScheduledTasks.

These are the equivalent for agents, but they are running directly in the HTTP task (which allows to access the complete Spring Application at runtime) and can be scheduled exactly to the milisecond.

To enable a scheduled task, you first have to add the @EnableScheduling annotation in your Application class:

package domino_spring.plugin;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;

@SpringBootApplication
@EnableScheduling
public class Application extends org.springframework.boot.web.support.SpringBootServletInitializer {

   public static void main(String[] args) {
      SpringApplication.run(Application.class, args);
   }

}

Next step is to declare the TaskScheduler used. Just add a bean to your Application class:

@Bean
 public TaskScheduler taskScheduler() {
      return new ConcurrentTaskScheduler();
 }

After completing the setup you can define your scheduled task:

package domino_spring.plugin;

import java.text.SimpleDateFormat;
import java.util.Date;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

@Component
public class ScheduledTasks {

   private static final Logger log = LoggerFactory.getLogger(ScheduledTasks.class);

   private static final SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");

   @Scheduled(fixedRate = 5000)
   public void reportCurrentTime() {
      log.info("The time is now {}", dateFormat.format(new Date()));
   }
 
}

When the Sprint Boot application is now started, the current time is  printed to the logs every 5 seconds.

2018 kann losgehen

2. Februar 2018 Posted by Stephan Kopp

Ich weiß es ist schon Februar, aber ich hatte die letzten 3 Wochen Urlaub und starte sozusagen erst jetzt so richtig ins neue Jahr. Ich bin kein Freund von guten Vorsätzen, primär weil ich mich eh selten daran halte. Trotzdem hat natürlich jeder so seine Vorstellungen und Wünsche an ein neues Jahr und blickt auf das Vergangene zurück.

Beruflicher Wandel

Mein Berufsleben habe ich als Lotus Notes Entwickler gestartet, das ist mittlerweile schon ein paar Jährchen her. Vor einigen Jahren, als das Ende dieser Ära abzusehen war, habe ich angefangen mich auch mit anderen Dingen zu beschäftigen. Nach einigen Experimenten bin ich dann bei Java, dem Vaadin und Spring Boot Framework gelandet. Rückblickend kann ich sagen, dass ich letztes Jahr nun erstmals mehr Zeit mit diesen neuen Themen verbracht habe und weniger mit Lotus Notes. Das Thema Notes/Domino wird mich natürlich auch weiterhin begleiten, aber ich denke der Fokus wird sich weiter darauf konzentrieren, die Kunden bestmöglich bei der Ablösung zu beraten.

Mein persönlicher Wunsch für dieses Jahr ist es, diese Projekte, die sich komplett jenseits der altbekannten Lotus Notes Welt bewegen weiter auszubauen. Die neuen Themen, Technologien und Konzepte wie Microservices, APIs, etc. machen mir viel mehr Spaß. Das sind herausfordernde Projekte und man hat die Gelegenheit sich in neue Themen und Ideen einzuarbeiten.

IBM Notes/Domino 10

Der Verkauf der Produkt Sparte hat einige Leute in der Community in helle Aufregung versetzt und positive Erwartungen und Hoffnungen geweckt. Persönlich hat mich das alles allerdings nicht überzeugt. Es ist eine naheliegende Entscheidung von IBM, aber die Hoffnung, dass mit Notes 10 jetzt eine echte Weiterentwicklung auf uns zukommt kann ich nicht teilen. Meiner Meinung nach ist das allerhöchstens eine Produktpflege, um den Kunden ein wenig den Druck von den Schultern zu nehmen, Notes möglichst schnell abzulösen. Das kommt allerdings einige Jahre zu spät und die meisten haben das Thema „End of Lotus Notes“ schon fest auf der Agenda.

Soll jetzt nicht heißen, dass ich Kunden jede Investition in die Plattform versuche auszureden. Wer weiter darauf setzen will, hat jetzt einen validen Fahrplan für die nächsten Jahre und kann bestehende Applikationen mit gutem Gewissen weiterentwickeln. Ich persönlich setze meinen Fokus aber nicht mehr auf Lotus Notes, sondern will mich weiterentwickeln und mich um interessantere Themen kümmern.

Work Life Balance

Das ist ein sehr überstrapazierter Begriff, aber für mich hat das Thema einen hohen Stellenwert. Ich arbeite um zu leben, aber ich lebe nicht nur um zu arbeiten. Natürlich stecke ich viel Zeit und Mühe in meinen Job, aber kann meine Freizeit und Urlaub auch sehr genießen. Der Start in das Jahr 2018 mit einer ausgedehnten Asien Reise war hierfür ein guter Anfang und sicher nicht meine letzte Auszeit dieses Jahr.

Das neue Jahr kann also kommen und ich bin gespannt, was mich erwartet.

2018 kann losgehen

2. Februar 2018 Posted by Stephan Kopp

Ich weiß es ist schon Februar, aber ich hatte die letzten 3 Wochen Urlaub und starte sozusagen erst jetzt so richtig ins neue Jahr. Ich bin kein Freund von guten Vorsätzen, primär weil ich mich eh selten daran halte. Trotzdem hat natürlich jeder so seine Vorstellungen und Wünsche an ein neues Jahr und blickt auf das Vergangene zurück.

Beruflicher Wandel

Mein Berufsleben habe ich als Lotus Notes Entwickler gestartet, das ist mittlerweile schon ein paar Jährchen her. Vor einigen Jahren, als das Ende dieser Ära abzusehen war, habe ich angefangen mich auch mit anderen Dingen zu beschäftigen. Nach einigen Experimenten bin ich dann bei Java, dem Vaadin und Spring Boot Framework gelandet. Rückblickend kann ich sagen, dass ich letztes Jahr nun erstmals mehr Zeit mit diesen neuen Themen verbracht habe und weniger mit Lotus Notes. Das Thema Notes/Domino wird mich natürlich auch weiterhin begleiten, aber ich denke der Fokus wird sich weiter darauf konzentrieren, die Kunden bestmöglich bei der Ablösung zu beraten.

Mein persönlicher Wunsch für dieses Jahr ist es, diese Projekte, die sich komplett jenseits der altbekannten Lotus Notes Welt bewegen weiter auszubauen. Die neuen Themen, Technologien und Konzepte wie Microservices, APIs, etc. machen mir viel mehr Spaß. Das sind herausfordernde Projekte und man hat die Gelegenheit sich in neue Themen und Ideen einzuarbeiten.

IBM Notes/Domino 10

Der Verkauf der Produkt Sparte hat einige Leute in der Community in helle Aufregung versetzt und positive Erwartungen und Hoffnungen geweckt. Persönlich hat mich das alles allerdings nicht überzeugt. Es ist eine naheliegende Entscheidung von IBM, aber die Hoffnung, dass mit Notes 10 jetzt eine echte Weiterentwicklung auf uns zukommt kann ich nicht teilen. Meiner Meinung nach ist das allerhöchstens eine Produktpflege, um den Kunden ein wenig den Druck von den Schultern zu nehmen, Notes möglichst schnell abzulösen. Das kommt allerdings einige Jahre zu spät und die meisten haben das Thema „End of Lotus Notes“ schon fest auf der Agenda.

Soll jetzt nicht heißen, dass ich Kunden jede Investition in die Plattform versuche auszureden. Wer weiter darauf setzen will, hat jetzt einen validen Fahrplan für die nächsten Jahre und kann bestehende Applikationen mit gutem Gewissen weiterentwickeln. Ich persönlich setze meinen Fokus aber nicht mehr auf Lotus Notes, sondern will mich weiterentwickeln und mich um interessantere Themen kümmern.

Work Life Balance

Das ist ein sehr überstrapazierter Begriff, aber für mich hat das Thema einen hohen Stellenwert. Ich arbeite um zu leben, aber ich lebe nicht nur um zu arbeiten. Natürlich stecke ich viel Zeit und Mühe in meinen Job, aber kann meine Freizeit und Urlaub auch sehr genießen. Der Start in das Jahr 2018 mit einer ausgedehnten Asien Reise war hierfür ein guter Anfang und sicher nicht meine letzte Auszeit dieses Jahr.

Das neue Jahr kann also kommen und ich bin gespannt, was mich erwartet.

Es war einmal ein Lotus Notes Entwickler – Alles hat irgendwann ein Ende

21. Dezember 2016 Posted by Stephan Kopp

Ok, etwas überspitzt, aber dennoch wahr. Notes wird mich und Andere noch lange begleiten, aber bis zu meiner Rente schaffe ich es damit sicherlich nicht.

IBM hat meiner Meinung nach leider kein wirkliches Interesse die Plattform weiter zu entwickeln. So lange es geht, werden die bestehenden Kunden mit „Feature Packs“ noch bei der Stange gehalten, aber mehr nicht. Auch IBM Verse on premise wird daran nichts ändern. Deshalb sollte sich jeder über die Zeit danach Gedanken zu machen.

Wohin mit den ganzen Applikationen? Wirklich alles neu entwickeln? Alles nach Sharepoint oder sonst wohin „migrieren“? Ein solches Projekt ist ein Monster, das kaum jemand angehen und schon garnicht bezahlen möchte.

Ich bin kein Fan des „R.I.P. and Replace“ Ansatzes, den viele bevorzugen. Bei einfachen Applikationen und irgendwelchen Standard Anwendungsfällen mag soetwas machbar und sinnvoll sein. Wir sollten uns aber bei komplexen Applikationen eher ganz gezielt diese zwei Fragen stellen:

  1. Was können wir neu entwickeln um einen Mehrwert für die jeweilige Anwendung zu bieten?
  2. Wie können wir das mit „nicht Notes” Technologien machen und es an die bestehende Applikation anbinden?

In letzter Zeit habe ich mich sehr viel mit REST Schnittstellen und Webservices beschäftigt und auch ein wenig mit Vaadin und Spring Boot. Diese Technologien bieten im Grunde alles, was wir benötigen um beide Fragen zu beantworten.

Nachfolgend ein kleines Szenario, bei dem wir diesen Ansatz konkret umsetzen konnten. Es ging um eine bestehende Notes Applikation, die verwendet wird um andere Applikationen in ein Langzeit Archiv zu verschieben sobald sie nichtmehr verwendet werden. Hierfür sollte ein Webinterface entwickelt werden.

  • Wir benötigen ein Browser Interface, aber der Entwickler (ich) hat kein Händchen für HTML und CSS:  Vaadin
  • Ein Application Server jenseits von Domino ist nicht vorhanden und auch nicht erwünscht: Spring Boot
  • Bestehende Daten und Funktionen aus Notes Applikationen sollen eingebunden werden: REST API oder Webservices

Entstanden ist ein recht ansehnliches Webinterface, das Daten aus einer Notes Applikation darstellt und auch Funktionalitäten aus dieser Applikation ansteuern kann. Hierzu wurden einige bestehende Funktionen als Webservices zur Verfügung gestellt und eingebunden.

archiving-selfservice-01 archiving-selfservice-02

Dieser Ansatz gefällt mir persönlich am besten und zwar aus folgenden Gründen:

  1. Der Aufwand und damit die Kosten sind überschaubar.
  2. Die Anwender haben sofort etwas davon, da wir uns zunächst auf neue Funktionen konzentrieren und nicht erst langwierig das nachbauen müssen, was eh schon vorhanden ist.
  3. Langfristig wird sicher auch irgendwann die Notes Applikation abgelöst, aber vorerst kann man seine Investition schützen und muss nicht bei Null anfangen.
  4. Sind nach und nach immer mehr Funktionen aus Notes hinaus gewandert, kann irgendwann auch der Data Store z.B. auf eine Mongo DB, Couch DB oder was auch immer umgestellt werden.
  5. Das Knowhow der eigenen Entwickler, Admins oder Partner entwickelt sich weiter.

Ich will damit nicht sagen, dass wir alle Notes Applikation in diesem Stil migrieren sollten. Es ist nur ein Beispiel, das in unserem Fall gut funktioniert hat. In anderen Fällen machen andere Technologien vielleicht mehr Sinn. Falls eine Application Server Infrastruktur vorhanden ist, kann diese auch mit verwendet werden und man kann auf Spring Boot verzichten.

Was ich sagen will ist, dass ich jedem Notes Entwickler sehr empfehle sich aktiv in den Entscheidungsprozess einzubringen, was zukünftig mit den Notes Applikationen geschehen soll. Ansonsten wird diese Entscheidung woanders getroffen und oft landen dann mit dem Produkt auch die zugehörigen Personen auf dem Abstellgleis und das wollen wir ja alle nicht.


Filed under: Development, IBM Notes/Domino, Vaadin

Auf der Suche nach Alternativen: Vaadin + Spring Boot

4. September 2016 Posted by Stephan Kopp

Die ganze Diskussion über die Zukunft von IBM Notes/Domino ist sehr müßig und darauf habe ich eigentlich gar keine Lust mehr. Ich für meinen Teil beschäftige mich sehr gerne mit neuen Themen und schaue mich daher ganz automatisch immer auch nach Alternativen um.

Das Konzept von Node.js und vor allem in Kombination mit AngularJS gefällt mir sehr. Einige REST Services mit Anbindung an Domino Daten habe ich damit auch schon für Kunden umgesetzt. Ich bin aber ehrlich gesagt kein großer Freund von JavaScript. Mir persönlich fehlt einfach der klassische Ansatz der Objekt orientierten Programmierung, außerdem tue ich mir mit dem Oberflächen Design in HTML auch sehr schwer.

Zuletzt bin ich aufgrund eines Erfahrungsberichtes über das Vaadin Framework gestolpert und war auf den ersten Blick begeistert. Das Prinzip ist im Grunde sehr ähnlich zur klassischen Notes Entwicklung. Mit sehr wenig Aufwand halbwegs ansehnliche Business Applikationen zu entwicklen. Ja, Notes war damals auch durchaus ansehnlich. Was mich allerdings wiederum abgeschreckt hat, war die Notwendigkeit eines Applikationsservers. Sicher, man kann Domino verwenden und die Vaadin Applikation in ein OSGi Plugin packen, aber dadurch steckt man eigentlich wieder in genau der selben Zwickmühle wie jetzt auch. Man ist abhängig von Java Versionen, Server Upgrade Zyklen, etc. Wenn ein Kunde im großen Stil auf solche Applikationen setzen möchte, macht eine Server Infrastruktur mit Backup, Hochverfügbarkeit, Rechte Konzept, etc. natürlich Sinn. Die Flexibilität geht dabei aber verloren.

Die Node.js Applikationen, die ich für einen meiner Kunden entwickelt habe, war ein gutes Beispiel. Es war völlig egal auf welcher Technologie wir entwickeln, aber wenn ich als Voraussetzung einen Application Server genannt hätte, wäre es nicht mehr so egal gewesen. Dann hätte das eine Menge zusätzlichen Aufwand, Abstimmungen und Entscheidungen nach sich gezogen. Statt dessen habe ich einfach eine Node.js Applikation irgendwo als Windows Service konfiguriert und seit dem läuft die Applikation ohne Probleme. Ich war nicht abhängig von irgendwelchen Server Versionen oder sonst irgendwas. Alles was ich benötige, packe ich in meine Applikation.

Das Vaadin Framework alleine kann diese Anforderung nicht erfüllen. Vor einiger Zeit habe ich mich aber auch mit Spring Boot beschäftigt. Vaadin und Spring Boot in Kombination erfüllen auf den ersten Blick all meine Erwartungen. Mit Vaadin entwickle ich meine Applikation und das Frontend und über Spring Boot integriere ich quasi einen Application Server und viele weitere nützliche Dinge, wie z.B. eine Authentifizierung gegen ein LDAP Verzeichnis.

Ich habe aktuell zwei Projekte auf meiner ToDo Liste, für die genau dieses Konzept sinnvoll wäre. Falls es zeitlich möglich ist, würde ich diese beiden Projekte mal sozusagen als Testballon mit Vaadin und Spring Boot implementieren. Als Backend werde ich per REST API auf Domino Daten zugreifen und über Webservices komplexere Funktionen ansprechen. Meine Erfahrungen, ob das Experiment erfolgreich war, werde ich hier bei Gelegenheit erzählen…

Falls jemand schon Erfahrung zu dem Thema gemacht hat, würde ich mich über Feedback sehr freuen.


Filed under: Development, IBM Notes/Domino

Auf der Suche nach Alternativen: Vaadin + Spring Boot

4. September 2016 Posted by Stephan Kopp

Die ganze Diskussion über die Zukunft von IBM Notes/Domino ist sehr müßig und darauf habe ich eigentlich gar keine Lust mehr. Ich für meinen Teil beschäftige mich sehr gerne mit neuen Themen und schaue mich daher ganz automatisch immer auch nach Alternativen um.

Das Konzept von Node.js und vor allem in Kombination mit AngularJS gefällt mir sehr. Einige REST Services mit Anbindung an Domino Daten habe ich damit auch schon für Kunden umgesetzt. Ich bin aber ehrlich gesagt kein großer Freund von JavaScript. Mir persönlich fehlt einfach der klassische Ansatz der Objekt orientierten Programmierung, außerdem tue ich mir mit dem Oberflächen Design in HTML auch sehr schwer.

Zuletzt bin ich aufgrund eines Erfahrungsberichtes über das Vaadin Framework gestolpert und war auf den ersten Blick begeistert. Das Prinzip ist im Grunde sehr ähnlich zur klassischen Notes Entwicklung. Mit sehr wenig Aufwand halbwegs ansehnliche Business Applikationen zu entwicklen. Ja, Notes war damals auch durchaus ansehnlich. Was mich allerdings wiederum abgeschreckt hat, war die Notwendigkeit eines Applikationsservers. Sicher, man kann Domino verwenden und die Vaadin Applikation in ein OSGi Plugin packen, aber dadurch steckt man eigentlich wieder in genau der selben Zwickmühle wie jetzt auch. Man ist abhängig von Java Versionen, Server Upgrade Zyklen, etc. Wenn ein Kunde im großen Stil auf solche Applikationen setzen möchte, macht eine Server Infrastruktur mit Backup, Hochverfügbarkeit, Rechte Konzept, etc. natürlich Sinn. Die Flexibilität geht dabei aber verloren.

Die Node.js Applikationen, die ich für einen meiner Kunden entwickelt habe, war ein gutes Beispiel. Es war völlig egal auf welcher Technologie wir entwickeln, aber wenn ich als Voraussetzung einen Application Server genannt hätte, wäre es nicht mehr so egal gewesen. Dann hätte das eine Menge zusätzlichen Aufwand, Abstimmungen und Entscheidungen nach sich gezogen. Statt dessen habe ich einfach eine Node.js Applikation irgendwo als Windows Service konfiguriert und seit dem läuft die Applikation ohne Probleme. Ich war nicht abhängig von irgendwelchen Server Versionen oder sonst irgendwas. Alles was ich benötige, packe ich in meine Applikation.

Das Vaadin Framework alleine kann diese Anforderung nicht erfüllen. Vor einiger Zeit habe ich mich aber auch mit Spring Boot beschäftigt. Vaadin und Spring Boot in Kombination erfüllen auf den ersten Blick all meine Erwartungen. Mit Vaadin entwickle ich meine Applikation und das Frontend und über Spring Boot integriere ich quasi einen Application Server und viele weitere nützliche Dinge, wie z.B. eine Authentifizierung gegen ein LDAP Verzeichnis.

Ich habe aktuell zwei Projekte auf meiner ToDo Liste, für die genau dieses Konzept sinnvoll wäre. Falls es zeitlich möglich ist, würde ich diese beiden Projekte mal sozusagen als Testballon mit Vaadin und Spring Boot implementieren. Als Backend werde ich per REST API auf Domino Daten zugreifen und über Webservices komplexere Funktionen ansprechen. Meine Erfahrungen, ob das Experiment erfolgreich war, werde ich hier bei Gelegenheit erzählen…

Falls jemand schon Erfahrung zu dem Thema gemacht hat, würde ich mich über Feedback sehr freuen.