Skip to content

GridGain-Demos/spring-data-training

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

70 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Project Template for Apache Ignite With Spring Boot and Spring Data Training

This project template is used throughout a two-hour training session for Java developers and architects who want to explore the best practices and nuances of using Spring Boot and Spring Data with Apache Ignite (or GridGain). During that instructor-led training, you build a RESTful web service that uses Apache Ignite as an in-memory database. The service is a Spring Boot application that interacts with the Ignite cluster via Spring Data repository abstractions.

Check the schedule a join one of our upcoming sessions. All the sessions are delivered by seasoned Ignite experts and committers.

Setting Up Environment

Note 1

This project has been tested most thoroughly using Java 17 and GridGain 9.1.8. (GridGain 9 supports Java 11, but the minimum version for Spring Boot is Java 17.) Later versions may work; earlier versions will not. We test most frequently on Macs, but it should also work on Windows and Linux machines. Please create an Issue (or a PR!) if you find any issues.

Note 2

This project currently uses Spring Boot and Data 3.x. GridGain 9.1.19 and higher supports Spring 4.x.

Hands-on part 1

1. Clone the Project

Open a terminal window and clone the project to your dev environment:

git clone https://github.com/GridGain-Demos/spring-data-training.git

2. Start your GridGain cluster

  1. Start your nodes using Docker Compose:

    docker compose up -d
  2. Initialize your cluster:

    a. Start the Command Line Interface (CLI):

    docker run -v ./gridgain-license.json:/opt/gridgain/downloads/gridgain-license.json -v ./config/world.sql:/opt/gridgain/downloads/world.sql --rm --network spring-boot-data-training_default -it gridgain/gridgain9:9.1.8 cli

    (Ensure your license file is in your current directory.)

    b. Connect to the cluster.

    connect http://node1:10300

    c. Execute command to initialize the cluster:

    cluster init --name=spring-data-training --metastorage-group=node1,node2,node3 --license=/opt/gridgain/downloads/gridgain-license.json

Leave the CLI connected to the cluster.

3. Load World Database

  1. In the same CLI window, load the media store database by executing the SQL command to load the sample data.

    sql --file=/opt/gridgain/downloads/world.sql

Hands-on part 2

4. Configure Ignite Spring Boot and Data Extensions

  1. Enable Ignite Spring Boot and Spring Data extensions by adding the following artifacts to the pom.xml file

    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-data-jdbc</artifactId>
    </dependency>
    
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-test</artifactId>
      <scope>test</scope>
    </dependency>
    
    <dependency>
       <groupId>${ignite.project}</groupId>
       <artifactId>spring-data-ignite</artifactId>
       <version>${ignite.version}</version>
    </dependency>
    
    <dependency>
       <groupId>${ignite.project}</groupId>
       <artifactId>spring-boot-starter-ignite-client</artifactId>
       <version>${ignite.version}</version>
    </dependency>
  2. Configure Spring Data to speak the right SQL dialect. Create a file resources/META-INF/spring.factories and add the following parameter:

    org.springframework.data.jdbc.repository.config.DialectResolver$JdbcDialectProvider=org.apache.ignite.data.IgniteDialectProvider

5. Configure Spring Boot to connect to Ignite

  1. Update the application.properties by adding an option that tells Spring Boot where to find the Ignite server node:

     ignite.client.addresses=127.0.0.1:10800
     spring.datasource.url=jdbc:ignite:thin://localhost:10800/
     spring.datasource.driver-class-name=org.apache.ignite.jdbc.IgniteJdbcDriver
  2. Edit the Application.java class. Autowire our connection to the Ignite servers:

    @Autowired
    private Ignite ignite;
  3. Add some diagnostics code to run when the server starts:

    private Logger log = LoggerFactory.getLogger(Application.class);
    
    @EventListener(ApplicationReadyEvent.class)
    public void startupLogger() {
        log.info("Table names existing in cluster: {}", ignite.tables().tables().stream().map(Table::name).toList());
    
        log.info("Node information:");
        for (var n : ignite.cluster().nodes()) {
            log.info("ID: {}, Name: {}, Address: {}", n.id(), n.name(), n.address());
        }
    }
  4. Run your new Spring Boot application. It should connect to your Ignite servers and list information about the tables and cluster topology

Hand-on part 3

6. Run Simple Auto-Generated Queries Via Ignite Repository

  1. Create the CountryRepository class (in the com.gridgain.training.spring package):

    @Repository
    public interface CountryRepository extends CrudRepository<Country, String> {
    
    }
  2. Add a method that returns countries with a population bigger than provided one:

    List<Country> findByPopulationGreaterThanOrderByPopulationDesc(int population);
  3. Add a test in ApplicationTests (in the src/test folder) that validates that the method returns a non-empty result:

    @Test
    void countryRepositoryWorks() {
      var results = countryRepository.findByPopulationGreaterThanOrderByPopulationDesc(100_000_000);
      System.out.println("count=" + results.size());
      Assertions.assertTrue(results.size() > 0);
    }

    Add the following line after ApplicationTests class declaration:

    @Autowired CountryRepository countryRepository;
  4. Run the tests:

    mvn compile test

7. Run Direct Queries With JOINs Via Spring Data JDBC Repository

  1. Create the CityRepository class (in the com.gridgain.training.spring package) :

    @Repository
    public interface CityRepository extends CrudRepository<City, Integer> {
    }
  2. Add a direct SQL query that joins two tables:

    record PopulousCity(String cityName, Integer population, String countryName) {}
    
    @Query("SELECT city.name as city_name, MAX(city.population) as population, country.name as country_name FROM country " +
          "JOIN city ON city.countrycode = country.code " +
          "GROUP BY city.name, country.name, city.population " +
          "ORDER BY city.population DESC LIMIT :limit")
    public List<PopulousCity> findTopXMostPopulatedCities(int limit);
  3. Create a test in ApplicationTests to validate the methods respond properly:

    @Test
    void cityRepositoryWorks() {
        var city = cityRepository.findById(34);
        Assertions.assertTrue(city.isPresent());
        Assertions.assertEquals("Tirana", city.get().getName());
    
        var populatedCities = cityRepository.findTopXMostPopulatedCities(5);
        Assertions.assertEquals(5, populatedCities.size());
        Assertions.assertEquals("Mumbai (Bombay)", populatedCities.get(0).cityName());
    }

    Add the following line after ApplicationTests class declaration:

    @Autowired CityRepository cityRepository;
  4. Run the tests:

    mvn compile test

Hands-on part 4

8. Create Spring REST Controller

In this section, we'll bring together the REST end-points supported by Spring Boot and the database access provided by Spring Data. By starting GridGain and loading the data (as mentioned in the above steps), this code can be directly used for the REST APIs.

  1. Create a REST Controller for the application by creating a new class named WorldDatabaseController (in the com.gridgain.training.spring package) with the following contents:

    @RestController
    public class WorldDatabaseController {
        @Autowired CityRepository cityRepository;
    
    }
  2. Add a method that returns top X most populated cities:

    @GetMapping("/api/mostPopulated")
    public List<CityRepository.PopulousCity> getMostPopulatedCities(@RequestParam(value = "limit", required = false, defaultValue = "10") Integer limit) {
        return cityRepository.findTopXMostPopulatedCities(limit);
    }
  3. Restart the Application and then test the controller method either in REST endpoint viewer: http://localhost:8080/api/mostPopulated?limit=5

Hands-on wrap-up

When you have finished the exercises, you can shut down your cluster.

  1. Shut down the client application in your IDE

  2. Shut down your cluster with the following command:

    docker compose -f docker-compose.yaml down

    The "down" command shuts down and deletes the containers. You can also use the "stop" command, which stops the cluster but keeps the containers, meaning that they can be restarted.

About

Template project for Apache Ignite with Spring Boot and Spring Data Training

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages