Details
-
Bug
-
Status: Open
-
Major
-
Resolution: Unresolved
-
2.1, 2.2
-
None
-
None
-
OS: OSX 10.12
Java: 1.8.0_112-b16
Kotlin: 1.1.4-3
Description
@SpringResource block Service Node bootstrap and service deployment when the node starts at the first time. After killing the service node and restarting, the service is deployed successfully.
My steps is
1. Start the data node
```
fun main(args: Array<String>) {
SpringApplication(DataNodeApplication::class.java).apply {
addInitializers(
ApplicationContextInitializer<GenericApplicationContext>
)
}.run(*args)
}
@SpringBootConfiguration
@EnableAutoConfiguration
class DataNodeApplication {
companion object {
fun beans() = beans {
bean("igniteInstance") {
// Ignite configuration with all defaults
// and enabled p2p deployment and enabled events.
val igniteConfig = IgniteConfiguration().apply {
isPeerClassLoadingEnabled = true
/*
Labeling Data Nodes with special attribute.
This attribute is checked by common.filters.DataNodeFilters
which decides where caches have to be deployed.
*/
userAttributes = mutableMapOf("data.node" to true)
// Configuring caches that will be deployed on Data Nodes
setCacheConfiguration(
// Cache for QuoteRequest
CacheConfiguration<Int, QuoteRequest>().apply
,
// Cache for Maintenance records
CacheConfiguration<Int, Maintenance>().apply {
name = "maintenance"
/*
Enabling a special nodes filter for the cache. The filter
will make sure that the cache will be deployed only on Data
Nodes, the nodes that have 'data.node' attribute in the local
node map.
*/
nodeFilter = DataNodeFilter()
// Enabling our sample cache store for the Maintenance cache
setCacheStoreFactory(FactoryBuilder.factoryOf("common.cachestore.SimpleCacheStore"))
// Avoid Maintenance objects deserialization on data nodes side
// when they are passed to SampleCacheStore.
isStoreKeepBinary = true
// Enabling the write-through feature for the store.
isWriteThrough = true
// Enabling the read-through feature for the store.
isReadThrough = true
// Configuring SQL schema.
queryEntities = listOf(
QueryEntity().apply
)
}
)
discoverySpi = discoverySpi()
}
IgniteSpringBean().apply
{ configuration = igniteConfig }}
}
}
}
```
2. Start the service node
```
fun main(args: Array<String>) {
SpringApplication(RequestForQuoteServiceNode::class.java).apply {
addInitializers(
ApplicationContextInitializer<GenericApplicationContext> { RequestForQuoteServiceNode.beans().initialize(it) }
)
}.run(*args)
}
@SpringBootConfiguration
@EnableAutoConfiguration
@EnableIgniteRepositories("repository")
class RequestForQuoteServiceNode {
companion object {
fun beans() = beans {
bean("igniteInstance") {
// Ignite configuration with all defaults
// and enabled p2p deployment and enabled events.
val igniteConfig = IgniteConfiguration().apply {
isPeerClassLoadingEnabled = true
/*
Labeling QuoteRequest Service nodes with special attribute.
This attribute is checked by common.filters.VehicleServiceFilter.
Due to the filter, the RequestForQuoteService might be deployed only on
the nodes with this special attribute set.
*/
userAttributes = mutableMapOf("vehicle.service.node" to true)
setServiceConfiguration(
// Setting up RequestForQuoteService.
// The service will be deployed automatically
// according to the configuration below.
ServiceConfiguration().apply { name = "RequestForQuoteService" // Don't initialize service's properties here. Ignite's deployment // will discard them. service = RequestForQuoteServiceImpl() // Only one instance of the service will be deployed cluster wide totalCount = 1 // Only one instance of the service can be deployed on a single node. maxPerNodeCount = 1 /* Enabling a special nodes filter for this service. The filter will make sure that the service will be deployed only on the nodes that have 'quoteRequest.service.node' attribute in the local node map. */ nodeFilter = VehicleServiceFilter() }
)
discoverySpi = discoverySpi()
}
IgniteSpringBean().apply { configuration = igniteConfig }
}
}
}
}
```
class RequestForQuoteServiceImpl : RequestForQuoteService {
@Transient @SpringResource(resourceClass = QuoteRequestRepository::class)
lateinit var quoteRequestRepository: QuoteRequestRepository
@IgniteInstanceResource
lateinit var ignite: Ignite
/** Reference to the cache. */
lateinit private var quoteRequestCache: IgniteCache<Int, QuoteRequest>
/**
{@inheritDoc} */override fun init(ctx: ServiceContext) { println("Initializing RequestForQuote Service on node:" + ignite.cluster().localNode()) /** * It's assumed that the cache has already been deployed. To do that, make sure to start Data Nodes with * a respective cache configuration. */ quoteRequestCache = ignite.cache("QuoteRequest") }
/** {@inheritDoc}
*/
override fun execute(ctx: ServiceContext)
/**
{@inheritDoc} */override fun cancel(ctx: ServiceContext) { println("Stopping QuoteRequest Service on node:" + ignite.cluster().localNode()) // Some custom logic. }
/** {@inheritDoc}
*/
override fun addQuoteRequest(quoteRequestId: Int, quoteRequest: QuoteRequest)
/**
{@inheritDoc} */override fun getQuoteRequest(quoteRequestId: Int): QuoteRequest { return quoteRequestCache.get(quoteRequestId) }
/** {@inheritDoc}
*/
override fun removeQuoteRequest(quoteRequestId: Int)
}
```
```
interface RequestForQuoteService : Service {
/**
- Calls the service to add a new quoteRequest.
* - @param quoteRequestId QuoteRequest unique ID.
- @param quoteRequest QuoteRequest instance to add.
*/
fun addQuoteRequest(quoteRequestId: Int, quoteRequest: QuoteRequest)
/**
- Calls the service to get details for a specific QuoteRequest.
* - @param quoteRequestId QuoteRequest unique ID.
*/
fun getQuoteRequest(quoteRequestId: Int): QuoteRequest
/**
- Calls the service to remove a specific vehicle.
* - @param quoteRequestId QuoteRequest unique ID.
*/
fun removeQuoteRequest(quoteRequestId: Int)
}
```
```
public class VehicleServiceFilter implements IgnitePredicate<ClusterNode> {
/**
- Checks if
{@code node}
needs to be considered as a QuoteRequest Service Node.
* - @param node Cluster node instance.
* - @return
{@code true}
if the node has to be considered as QuoteRequest Service Node,
{@code false}otherwise.
{ Boolean dataNode = node.attribute("vehicle.service.node"); return dataNode != null && dataNode; }
*/
public boolean apply(ClusterNode node)}
```
```
@RepositoryConfig(cacheName = "QuoteRequest")
interface QuoteRequestRepository : IgniteRepository<QuoteRequest, Int>
```