HowTo: Vaadin on Domino (3)

Let’s create another application, based on Vaadin’s AddressBook example. You can download the source code directly or grab the code from the repository; it is a single class file named „AddressbookUI“ only.

After importing (or manually creating) the class in the HelloVaadin plug-in, the servlet configuration in „web.xml“ must be updated:

<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

  <display-name>Addressbook</display-name>
    <context-param>
        <description>Vaadin production mode</description>
        <param-name>productionMode</param-name>
        <param-value>false</param-value>
    </context-param>
    
    <servlet>
        <servlet-name>AdressbookServlet</servlet-name>
        <servlet-class>com.vaadin.server.VaadinServlet</servlet-class>
        <init-param>
            <param-name>UI</param-name>
            <param-value>ch.hasselba.vaadin.AddressbookUI</param-value>
        </init-param>
    </servlet> 

    <servlet-mapping>
        <servlet-name>AdressbookServlet</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>
    
</web-app>

The „<param-value>“ must contain the complete class name, I have additionally changed the name of the servlet and updated the path in the „plugin.xml„:

<?xml version="1.0" encoding="UTF-8"?>
<?eclipse version="3.4"?>
<plugin>

     <extension
         point="com.ibm.pvc.webcontainer.application">
      <contextRoot>
         /addressbook  
      </contextRoot>
      <contentLocation>
         WebContent
      </contentLocation>
   </extension>

</plugin>

To connect the example to a Domino environment, the „createDummyDatasource“ method of the class must be replaced:

@SuppressWarnings("unchecked")
private static IndexedContainer createDummyDatasource() {

    // Domino objects
    Session session = null;
    Database db = null;
    View view = null;
    Document doc = null;
    Document tmpDoc = null;

    // initialize IndexedContainer
    IndexedContainer ic = new IndexedContainer();

    // add fieldnames as properties
    for (String p : fieldNames) {
        ic.addContainerProperty(p, String.class, "");
    }

    // get all users from NAB
    try{
        // init Domino objects
        session = ContextInfo.getUserSession();
        db = session.getDatabase(session.getServerName(), "dummynames.nsf");
        view = db.getView( "People" );

        // process all documents in view
        doc = view.getFirstDocument();
        while (doc != null) {

            // create a new item
            Object id = ic.addItem();

            // add field values to the item
            ic.getContainerProperty(id, FNAME).
                setValue(doc.getItemValueString("FirstName"));
            ic.getContainerProperty(id, LNAME).
                setValue(doc.getItemValueString("LastName"));

            // grab next document
            tmpDoc = doc;
            doc = view.getNextDocument(tmpDoc);
            recycle( tmpDoc );
        }
    }catch(Exception e){
        e.printStackTrace();
    }finally{
        recycle( doc, tmpDoc, view, db, session );
    }
    return ic;
}

/**
* recycle Domino objects
*
* @param objs
*     lotus.domino.Base objects to recylce
*/
private static void recycle(Base... objs){
    try{
        for( Base obj:objs ){
            if( obj != null )
                obj.recycle();
        }
    }catch(Exception e){}
}

Because this is not rocket science I won’t get into the details.

To prevent anonymous access, I have added a simple redirection in the „init“ method:

protected void init(VaadinRequest request) {
        
    if( ContextInfo.isAnonymous() ){
         getPage().setLocation("/names.nsf?login=1&redirectto=" + 
             request.getContextPath() );
         return;
    }
        
    initLayout();
    initContactList();
    initEditor();
    initSearch();
    initButtons();
}

When opening the application as an anonymous user you will be automatically redirected to the Login Screen:

00 - Login

After signing in, domino redirects back to the addressbook example, and the list of persons in your „names.nsf“ is shown up:

00 - Addressbook

Veröffentlicht unter OSGi, Vaadin | Verschlagwortet mit , , | 2 Kommentare

HowTo: Vaadin on Domino (2)

When running your own servlet, you eventually want to access the Domino environment. To do this, some changes has to be made to the HelloVaadin plug-in.

1. Open the „MANFIFEST.MF“ and open the „Dependencies“ tab

2. Add the plug-in „com.ibm.osgi.domino.core“ to the list of required plug-ins

01 - Dependencies - Add OSGi Plugin 00

01 - Dependencies - Add OSGi Plugin

01 - Dependencies - Add OSGi Plugin 02

Save the „MANIFEST.MF

3. Now we can use „com.ibm.domino.osgi.core.context.ContextInfo“ to access the Domino environment in HelloVaadinUI

package ch.hasselba.vaadin;

import lotus.domino.Database;
import lotus.domino.NotesException;
import lotus.domino.Session;
import com.vaadin.server.VaadinRequest;
import com.vaadin.server.VaadinServlet;
import com.vaadin.shared.ui.label.ContentMode;
import com.vaadin.ui.Label;
import com.vaadin.ui.UI; 
import com.vaadin.ui.VerticalLayout;
import com.ibm.domino.osgi.core.context.ContextInfo;

@SuppressWarnings("serial")
public class HelloVaadinUI extends UI {
    
    public static class Servlet extends VaadinServlet {
    }
    
    @Override
    protected void init(VaadinRequest request) {
    
        VerticalLayout layout = new VerticalLayout();
        setContent(layout);
        layout.setSizeFull();
        
        String dbPath = "";
        String userName = "";
        String queryString = "";
       
        try {
            
            // get the current database
            Database db = ContextInfo.getUserDatabase();
            if( db != null )
                dbPath = db.getFilePath();
            
            // get the current session
            Session session = ContextInfo.getUserSession();
            if( session != null )
                userName = session.getEffectiveUserName();
            
            // get the query string
            queryString = ContextInfo.getServerVariable("QUERY_STRING");
            
        } catch (NotesException e) {
            e.printStackTrace();
        }
        
        Label label = new Label();
        label.setValue("<h1>Hello " + userName + "!</h1>");
        label.setContentMode(ContentMode.HTML);
        
        Label labelDB = new Label();
        labelDB.setValue("<p>DB Path: " + dbPath + "</p>");
        labelDB.setContentMode(ContentMode.HTML);
        
        Label labelQuery = new Label();
        labelQuery.setValue("<p>Query: " + queryString + "</p>");
        labelQuery.setContentMode(ContentMode.HTML);
        
        layout.addComponents(label, labelDB, labelQuery);
    }

}

4. When opening the application inside the names.nsf, the result looks like this:

04  - Result

Veröffentlicht unter OSGi, Vaadin | Verschlagwortet mit , , | Schreib einen Kommentar

HowTo: Vaadin on Domino

This example requires a valid XPages Plugin Development Environment. The execution environment used is the XPages Domino JRE.

1. Create a new plug-in project and select „Equinox“ as OSGi framework

01 - New Plugin Project

2. Set the name of the activator class to „ch.hasselba.vaadin.Activator

02 - Activator Class

3. Open the MANIFEST.MF file

03 - Manifest

4. On Tab „Overview„, activate the option for lazy loading and the singleton property

04 - Singleton

5. Go to „Dependencies“ tab and add the required plugin „com.ibm.pvc.webcontainer

05 - Dependencies - Required Plugins 01

When entering „pvc„, you can easily find the plugin from the list:

05 - Dependencies - Required Plugins 02

6. Then, add  „javax.servlet“ and „javax.servlet.http“ to the list of imported packages

06 - Dependencies -ImportedPackages

7. Now, download the Jar files for Vaadin. The files can be found here (the All-in-One archive is the right one).

8. Import the Jars to the project

08 - Import - Vaadin Jars 01

08 - Import - Vaadin Jars 02

The required Jars are:

  • vaadin-client-7.3.8.jar
  • vaadin-client-compiled-7.3.8.jar
  • vaadin-client-compiler-7.3.8.jar
  • vaadin-push-7.3.8.jar
  • vaadin-server-7.3.8.jar
  • vaadin-shared-7.3.8.jar
  • vaadin-themes-7.3.8.jar

08 - Import - Vaadin Jars 03

9. Do this with „jsoup“ and „org.json“ libaries too:

09 - Import - Other Jar

10. Now, go to the „Runtime“ tab and add the classpathes (don’t forget to move the „.“ to the top of the list)

10 - Runtime - Classpath 02

10 - Runtime - Classpath

The symbol of the filetypes have now changed:

10 - Runtime - Classpath 03

11. On tab „Overview„, click on „Extensions“ to open the Extension tab

11 - Overview - Extensions

Click on „Yes“ to open the „Extension“ tab:

11 - Overview - Extensions 02

12. Here, you have to add the extension point „com.ibm.pvc.webcontainer.application

12 - Extension - Add 01

12 - Extension - Add 02

13. Open „plugin.xml“

13 - Plugin_XML

14. … and configure the extension point:

<?xml version="1.0" encoding="UTF-8"?>
<?eclipse version="3.4"?>
<plugin>

     <extension
         point="com.ibm.pvc.webcontainer.application">
      <contextRoot>
         /helloVaadin  
      </contextRoot>
      <contentLocation>
         WebContent
      </contentLocation>
   </extension>

</plugin>

contextRoot defines the URL pattern where the Vaadin servlet is reachable.  contentLocation is a folder where the required web.xml configuration file can be found.

Save the „plugin.xml“ file.

15. Create the folder „WebContent„…

15 - Folder 01

15 - Folder 02

16. … and then a second folder „WEB-INF“ inside of „WebContent

17. Create the „web.xml“ file in this folder, the tree should look like this:

17 - WebFolder Structure

18. The „web.xml“ contains the configuration of the servlet:

<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

  <display-name>HelloVaadin</display-name>
    <context-param>
        <description>Vaadin production mode</description>
        <param-name>productionMode</param-name>
        <param-value>false</param-value>
    </context-param>
    
    <servlet>
        <servlet-name>HelloVaadinServlet</servlet-name>
        <servlet-class>com.vaadin.server.VaadinServlet</servlet-class>
        <init-param>
            <param-name>UI</param-name>
            <param-value>ch.hasselba.vaadin.HelloVaadinUI</param-value>
        </init-param>
    </servlet> 

    <servlet-mapping>
        <servlet-name>HelloVaadinServlet</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>
    
</web-app>

The <init-param> tag inside <servlet> defines our UI class of our application. We will create this class later. The <servlet-mapping> defines a mapping inside the webapplication path.

This means, if you would add a url-pattern like „/helloVaadinServlet/*“ to the Vaadin servlet, the URL to reach the application is

http://example.com/helloVaadin/helloVaadinServlet/

The „/helloVaadin/“ part is the defined in the contextPath parameter in the web application. When using another pattern as „/*„, an additional mapping for the Vaadin resources is required:

<servlet-mapping>
        <servlet-name>HelloVaadinServlet</servlet-name>
        <url-pattern>/VAADIN/*</url-pattern>
</servlet-mapping>

19. Go to „Build“ tab, and include the „Web-Content“ folder:

19 - Build - Add WebContent 01

The following line should now appear in the build.properties file which includes the folder in the final Jar.

19 - Build - Add WebContent 02

20. Create the Vaadin servlet class „ch.hasselba.vaadin.HelloVaadinUI“

20. Servlet Class 01

20. Servlet Class 03

21. Add the following code to the class

package ch.hasselba.vaadin;

import com.vaadin.server.VaadinRequest;
import com.vaadin.server.VaadinServlet;
import com.vaadin.shared.ui.label.ContentMode;
import com.vaadin.ui.Alignment;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.Label;
import com.vaadin.ui.UI; 

@SuppressWarnings("serial")
public class HelloVaadinUI extends UI {
    
    public static class Servlet extends VaadinServlet {
    }
    
    @Override
    protected void init(VaadinRequest request) {
    
        HorizontalLayout layout = new HorizontalLayout();
        setContent(layout);
        layout.setSizeFull();

        Label label = new Label();
        label.setValue("<h1>Hello Vaadin!</h1>");
        label.setContentMode(ContentMode.HTML);
        layout.addComponent(label);
        layout.setComponentAlignment(label, Alignment.TOP_CENTER);
    }

}

22. At the end, organize the manifest. Open tab „Overview“ and start the „Organize Manifest Wizard

22 - Overview - Organize Manifest 01

22 - Overview - Organize Manifest 02

This updates the manifest and adds all resources for the Vaadin application.

22 - Overview - Organize Manifest 03

Last but not least, save all project files.

25. Create a Feature Project named „HelloVaadinFeature“ and click on „Next

Feature 00

27. Select the „HelloVaadin“ Plug-In

Feature 02

28. On the „Plugins“ tab, check the option „Unpack the plug-in archive after the installation„:

Feature 03

Save the file and…

29. … create the Update Site „HelloVaadinUpdateSite

UpdateSite 01

UpdateSite 02

Add the feature…

UpdateSite 03

UpdateSite 04

… and build the site:

UpdateSite 05

30. Import it to the Update Site on the Domino server and restart the HTTP task

31. That’s it! Open the URL in the browser and enjoy.

99 - Hello Vaadin

Veröffentlicht unter OSGi, Vaadin | Verschlagwortet mit , , | 8 Kommentare

Hardening SSH vs. Eclipse RSE

After hardening the SSH configuration on a Debian server by removing unsecure ciphers and MACs I got in trouble with Eclipse Remote System Explorer.

When trying to open the server, I always got an „Algorithm negotiation fail“ message:

Even installing the missing Unlimited Strength version of Java Crypto Extension which allows key sizes larger then 128 bit doesn’t helped me out.

The problem was the allowed KexAlgorithms and the list of MACs in the configuration:

Ciphers aes256-ctr,aes256-cbc
KexAlgorithms diffie-hellman-group-exchange-sha256
MACs hmac-sha2-512,hmac-sha2-256,hmac-ripemd160

After re-enabling the insecure default configuration by commenting out the both lines in the configuration allowed me to reconnect to the server again.

Ciphers aes256-ctr,aes256-cbc
#KexAlgorithms diffie-hellman-group-exchange-sha256
#MACs hmac-sha2-512,hmac-sha2-256,hmac-ripemd160

I don’t feel happy about it. But it seems that there is actually no workaround.

Veröffentlicht unter Security | 2 Kommentare

Yii: GridView’s selectionChanged not working on iOS

I had a strange issue with TbGridView’s (YiiStrap’s version of CGridView) selectionChanged event: In all browsers, the defined function was executed when a row was selected, but not on devices with iOS 7 & 8.

While trying to hack around the issue, I found a simple solution by adding

'htmlOptions' => array( 'onclick' => '' )

to the declaration of the grid. This little hack kills the inherited event handler from the body element by adding an empty onclick event to the generated <div>:

<div class="grid-view" id="yw0" onclick="">

Now everything works accross all browsers and devices.

Veröffentlicht unter Yii | Verschlagwortet mit , | Schreib einen Kommentar

REST & Security: CSRF Attacks

In this post I will demonstrate how a do a CSRF attack against a XPages REST service.

Let’s assume that we have a custom REST service on a XPage. To keep the example as simple as possible, this service returns the posted data back to the requesting browser only, nothing more and nothing less:

<?xml version="1.0" encoding="UTF-8"?>
<xp:view
    xmlns:xp="http://www.ibm.com/xsp/core"
    xmlns:xe="http://www.ibm.com/xsp/coreex"
    rendered="false">
    
    <xe:restService
        id="restService"
        pathInfo="foo">
        <xe:this.service>
            <xe:customRestService
                requestContentType="application/json"
                requestVar="data" 
                doPost="#{javascript:toJson( requestScope.data )}">
            </xe:customRestService>
        </xe:this.service>
    </xe:restService>

On my web server, I have created a simple HTML page with a form:

<html>
    <head />
    <body>
        <form name="CSRFAttack" enctype="text/plain"
            action="http://localhost/REST.nsf/CSRF.xsp/foo/" method="POST">
          <input type="hidden" name='{"Hello": "World"}'>
        </form> 

        <script>document.CSRFAttack.submit();</script>
    </body>
</html>

As soon a user (which is logged on my domino server) opens the HTML page, the form is automatically posted to the REST service.

1. User opens the „bad site“

2. Then the form is sent to the server

3. And the request is processed by the REST service


Et voilà, the CSRF attack was successfull.

Veröffentlicht unter REST, Security | Verschlagwortet mit , | 5 Kommentare

REST & Security

I am currently wearing my white hat and doing some pen and vulnerabilty tests for a RESTful API. While this is actually a hot topic in the Domino world, here are some resources:

 

Veröffentlicht unter Security | Verschlagwortet mit , | 11 Kommentare

Domino-Migration: Der frühe Vogel fängt den Wurm

Wenn die Entscheidung erst einmal gefallen ist, dass mittel- oder langfristig die Domino-Infrastruktur aus dem Unternehmen verschwinden wird, lässt die Investitionsbereitschaft der einzelnen Fachabteilungen in Domino-basierte Applikationen verständlicher Weise spürbar nach. Aber auch aufkommende Gerüchte oder durchgeführte Studien (auch wenn diese zu einem gegenteiligen Ergebnis kommen) können den Willen der IT- oder Geschäftsleitung nach einem Systemwechsel zu entsprechender Aussage verhelfen, und durch die aufkommende Ungewissheit zu dem gleichen Ergebniss führen.

Um dennoch zukunftssichere Applikationen zu entwickeln, bieten sich verschiedene Wege an, die sich (in Abhängigkeit zu der bestehenden und der zukünftigen Infrastruktur sowie der gewünschten strategischen Ausrichtung) jedoch stark unterscheiden können. Für jedes Unternehmen sind bestimmte Faktoren unterschiedlich zu bewerten, daher gibt es keinen „Königsweg“: Der zu beschreitende Weg ist immer individuell, und es müssen höchstwahrscheinlich ein paar Kompromisse eingegangen werden, um einen Übergang so geräuschlos wie nur möglich über die Bühne zu bringen.

Der mit Abstand wichtigste Punkt ist, sich möglichst früh vom liebgewonnenen Domino zu verabschieden, ohne eine falsch angebrachte Sentimentalität. Weitere wichtige Punkte, die es meiner Erfahrung zu beleuchten gilt, sind

  1. die gewünschte Form der Migration
  2. mögliche Ziel-Plattformen
  3. zunkünftige Datenhaltung
  4. die Authentifizierung der Anwender

Formen der Migration

Ist eine harte Migration gewünscht, sind praktisch alle Entscheidungen bereits getroffen, und eine weiteres Auseinandersetzen mit anderen Szenarien erübrigt sich: Sowohl Zielplatform als auch (Wunsch-)Termin stehen fest. Das Budget spielt dann wahrscheinlich auch keine Rolle, und ich wünsche viel Glück und gutes gelingen.

Wählt man hingegen eine weiche oder integrative Migrationen, erhöht sich der nötige Spielraum deutlich, und die Chance einer erfolgreichen Umstellung steigt, denn der Zeitdruck und das damit einhergebrachte Risiko eines Fehlschlages wird durch die Politik der kleinen (aber feinen) Schritte drastisch verringert.

Mögliche Zielplattformen

In einem Microsoft-lastigen Unternehmen bietet sich natürlich der IIS als Webserver an, um Applikationen darauf zu hosten. Der IIS unterstüzt neben den „Microsoft-eigenen“ Sprachen wie .NET auch weitere wie z.B. Java und PHP. Selbst Node.js wird unterstüzt.

Hier wäre also ein Ansatzpunkt, neue Applikationen direkt auf dem IIS zu betreiben. Falls momentan noch kein IIS im Einsatz ist, bietet es sich an, eine PHP-Applikationen auf dem Domino zu hosten, und diese dann später auf den IIS zu verschieben. Als Alternative kann auch ein Apache HTTP Server oder ein Tomcat dienen, wenn IT diesen betreiben kann (und will). Gleiches gilt natürlich auch für Node.js. Letztlich muss dieser Punkt mit der Administration abgeklärt werden.

Zieht man Client-basierte Applikationen (Stichwort „Angular JS“) in Betracht, kann die Applikation sogar in die Cloud verlagert werden, denn die Daten bleiben im Unternehmen: Zwar lädt der Browser die statischen Ressourcen aus der Cloud, doch werden die Daten vom Browser nur per REST-Schnittstelle im Unternehmensnetzwerk hin- und hergeschoben. Dadurch entfiele ein entsprechender administrativer Aufwand, die Applikation könnte auch von einem externen Anbieter problemlos betrieben werden (z.B. Bluemix).

Zukünftige Datenhaltung

Die Datenhaltung stellt wohl in bestimmten Stitautionen die größte Herausforderung dar, insbesondere wenn auch alte Daten migriert werden müssen. Gerade das Thema „Rich Text-Felder“ kann Probleme bereiten, denn je nach Verwendung wird es schwierig, bestehende Daten/Funktionalitäten 1:1 zu übernehmen. Auch einige eher selten genutzte Features auf Feldebene können eventuell nicht ohne erheblichen Aufwand abgebildet werden, doch muss man hier derweilen auch hinterfragen.

In den meisten Fällen sollte eine Umstellung allerdings Reibungslos möglich sein. Moderene Dokumentenbasierte Datenbanksysteme bieten einen ebenbürtigen Funktionsumfang, meist sogar noch deutlich mehr. Dennoch sollte meiner Erfahrung nach dieser Part nicht unterschätzt werden.

Authentifizierung

Eine wichtige Rolle stellt die Authentifizierung im Unternehmen dar: Wurde dies bisher vom Domino Server gehandelt, fällt diese Option zukünftig weg. Aber auch hierfür gibt es unterschiedliche Ansätze, je nachdem, woher die Applikation Ihre Daten erhält und wohin diese Daten abgelegt werden.

Wird der Domino Server nur zur Authenifizierung und nur einige Daten über den User benötigt, existiert mit LDAP eine relativ simple Lösung des Problems, die auch einfach migriert werden kann.

Sollen existierende Datenbanken angezapft werden, kann dieser Zugriff im Usercontext durch eine Proxy-Funktionalität geschehen (durch das Abgreifen/Durchschleifen des Domino Cookies). Eine spätere Umstellung kann dann für die Endapplikation transparent erfolgen, in dem letztlich der Code im Backend geändert wird, ohne das es hier zu Einschräkungen kommt.

Nutzer der Applikation

Ach, ein Thema habe ich bewusst aussen vor gelassen, dass aber ebenfalls eine große Rolle spielt: Die Nutzer der Applikation. Man darf Sie nie vergessen, und man muss versuchen, auf sie einzugehen, aber leider ist das die große Unbekannte, die praktisch unberechenbar ist: Es gibt Mitarbeiter, die sehr interessiert sind, und bei der Umstellung mitarbeiten. Gerade wenn die Möglichkeit dafür genutzt wird, das eine odere andere hilfreiche Zusatzfeature zu implementieren, und so den Mitarbeitern eine entsprechende Motivation zu bieten, wird verläuft eine Zusammenarbeit meist harmonisch und ertragreich. Letztlich sollte die Chance auf ein Redesign einer alten Applikation so gut wie möglich genutzt werden.

Aber man wird eventuell auch auf eine generelle Ablehnung stoßen, denn es war für die Mitarbeiter bisher möglich, viele Probleme im Arbeitsalltag auf „das Sch..ss Notes“ zu schieben. Diese Option entfällt zukünftig – was manchem Mitarbeiter in Erklärungsnot bringen könnte, und daher wird gemauert ohne Ende. Auch könnte es vorkommen, das vorhandene Features, die noch nie funktioniert haben, über Nacht zu Keyfeatures mutieren und deren „mangelnde Funktionalität“ die ganze Migration ad absurdum führen würden.

Da der „menschliche Faktor“ unberechenbar und damit unplanbar ist, kann (und sollte) er in der anfänglichen Planun nicht näher beachtet werden.

Fazit

Alles in allem lösbare Punkte, auf die ich im Einzelnen in den nächsten Tagen näher eingehen möchte. Es stehen noch Themen auf der Agenda, wie beispielsweise die Suche nach relevanten Applikationen, die migriert werden müssen. Und natürlich sollte die eine oder andere Anekdote, die ich in den letzten Jahren gesammelt habe, nicht fehlen.

Veröffentlicht unter Migration | 5 Kommentare

MongoDB for DBAs

After receiving my confirmation for MMDS today, I also received the confirmation for successfully completing the „MongoDB for DBAs“ course:

Here is the link to verify the certificate.

Veröffentlicht unter MongoDB | Verschlagwortet mit | 2 Kommentare

Mining Massive Datasets

I am very proud that I have successfully accomplished the MMDS course from Stanford University. It was unbelievable interesting to learn the theories and the mathematical basics of  topics like MapReduce, Web-link analysis, Data-streams, Locality-sensitive hashing, Computational advertising, Clustering, Recommender systems, Analysis of large graphs, Decision trees, Dimensionality reduction, Support-vector machines, and Frequent-itemset analysis.

It was really hard for me to follow all the topics, because I started to late (in the third week of the course), had a lot of work to do for my customers and have not seen any linear algebra since at least a decade. I had only the the nights to learn and to do the required homework. During the final examen,  my complete family was ill and I have to care them.

But in the end I did it:

Veröffentlicht unter Big Data | Verschlagwortet mit | Ein Kommentar