Saturday, March 12, 2016

Spring Data Neo4j - Cineasts.net

Cineasts.net


Cineasts.net is a project original from Misquitta Luanne which is based in the Spring Data Neo4j paradigma. In that project I have kindly added some new features to make it more functional and easy to use. I am talking about the posibbility to list all the movies as one of them.

The most relevant feature added to the project is Neo4j driver (REST API client) for Node.js which lets initialize the database of the web application if this does not exist. Here is the code,

var http = require('http');
var neo4j = require('neo4j');

var db = new neo4j.GraphDatabase('http://neo4j:neo@localhost:7474');

db.cypher({
    query: 'MATCH (user:User {login: {login}}) RETURN user',
    params: {
        login: 'micha',
    },
}, callback);

function callback(err, results) {
    if (err) {
        throw err;
    }
    var result = results[0];
    if (!result) {
        console.log('Database not found,');
        console.log('creating database...');

        http.get('http://localhost:8080/database', (res) => {
            console.log(`Got response: ${res.statusCode}`);
            console.log('run http://localhost:8080');
            // consume response body
            res.resume();
        }).on('error', (e) => {
            console.log(`Got error: ${e.message}`);
        });


    } else {
        //var user = result['user'];
        //console.log(user);
        console.log('Database found...');
        console.log('run http://localhost:8080');
    }
};

The question is if the database exists. To resolve it I ask by a cypher query for the user micha who is de administrator and he is created when the database is created as well. If the query returns a no result a GET is called to the URL 'http://localhost:8080/database'. See the Java code below,

@Controller
public class DatabaseController {
    
    @Autowired
    private DatabasePopulator populator;

    @RequestMapping(value = "/database", method = RequestMethod.GET)
    public String populateDatabase(Model model) {
        Collection<Movie> movies = populator.populateDatabase();
        model.addAttribute("movies", movies);
        return "index";
    }
}

where the code of method populateDatabase() from the class DatabasePopulator is as follows,
@Transactional
public List<Movie> populateDatabase() {
    importService.importImageConfig();
    User me = userRepository.save(new User("micha", "Micha", "password", User.SecurityRole.ROLE_ADMIN, User.SecurityRole.ROLE_USER));
    User ollie = new User("ollie", "Olliver", "password", User.SecurityRole.ROLE_USER);
    me.addFriend(ollie);
    userRepository.save(me);
    List<Integer> ids = asList(19995 , 194, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 13, 20526, 11, 1893, 1892,
              1894, 168, 193, 200, 157, 152, 201, 154, 12155, 58, 285, 118, 22, 392, 5255, 568, 9800, 497, 101, 120, 121, 122);
    List<Movie> result = new ArrayList<Movie>(ids.size());
    for (Integer id : ids) {
        result.add(importService.importMovie(String.valueOf(id)));
    }

    /*me.rate(movieRepository.findById("13"), 5, "Inspiring");
    final Movie movie = movieRepository.findById("603");
    me.rate(movie, 5, "Best of the series");*/
    
    return result;
}

You can get my complete proyect at GitHub - my-sdn4-cineasts.