/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package ignite

import io.gatling.core.Predef._
import io.gatling.core.feeder.Feeder
import io.gatling.core.structure.ScenarioBuilder
import io.netty.util.internal.ThreadLocalRandom
import org.apache.ignite.gatling.Predef._
import org.apache.ignite.gatling.protocol.IgniteProtocol
import org.apache.ignite.Ignite
import org.apache.ignite.Ignition

import scala.concurrent.duration.DurationInt
import scala.language.postfixOps

/**
 * Ignite gatling simulation example demonstrating:
 *
 * - Test scenario defined via the Ignite operations DSL.
 * - Group Ignite operations in transaction.
 * - Ignite gatling protocol configured via URL of the thin Ignite client Spring XML config file.
 * - Generate load with fixed RPS (100).
 *
 * Before run simulation start the Ignite server node manually on the localhost.
 */
class DslPutGetThinTx extends Simulation {
    // Start server ignite node before the simulation start.
    //
    // It is started at the same JVM the simulation would run just for simplicity.
    // In the real world testing conditions server ignite cluster nodes forming the cluster
    // under test would be started in some other way, outside the simulation class.
    private val server: Ignite = Ignition.start()

    /**
     * Feeder generating random test data for keys and values.
     */
    val feeder: Feeder[Int] = Iterator.continually(Map(
        "key" -> ThreadLocalRandom.current().nextInt(10000),
        "value" -> ThreadLocalRandom.current().nextInt()
    ))

    /**
     * Testing scenario defined via the Ignite operations DSL.
     *
     * Each operation like transaction start, put, get, commit will be measured and
     * represented in final HTML report separately.
     *
     * Besides, the gatling group will be created for transaction to measure it as a whole.
     */
    val scn: ScenarioBuilder = scenario("PutGetThinTx")
        .feed(feeder)
        .ignite(
            // Create cache if not exists.
            getOrCreateCache("cache") backups 1 atomicity TRANSACTIONAL mode PARTITIONED
                as "getOrCreateCache",

            // Setup and start the transaction.
            tx concurrency PESSIMISTIC isolation REPEATABLE_READ run (

                // Put random value.
                put[Int, Int]("cache", "#{key}", "#{value}") as "txPut",

                // Get and check that it's the same value as was put.
                get[Int, Int]("cache", "#{key}")
                    .check(
                        entries[Int, Int].transform(_.value).is("#{value}")
                    ) as "txGet",

                // Commit the transaction.
                commit as "txCommit"

            ) as "transaction"
        )

    // Create Ignite gatling protocol passing the path to thin client Spring XML configuration.
    val protocol: IgniteProtocol = igniteProtocol
        .clientCfgPath(
            Thread.currentThread().getContextClassLoader.getResource("ignite-thin-config.xml")
        )

    // Destroy the client node after the simulation.
    after {
        protocol.close()

        server.close()
    }

    setUp(
        scn.inject(
            // Generate constant 100 rps load for 30 seconds.
            constantUsersPerSec(100) during 30.seconds,
        )
    ).protocols(protocol)
        .assertions(global.failedRequests.count.is(0))
}
