blob: 7f58879086b4448020d145ac389cdd3935137b19 [file] [log] [blame]
/*
* 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 org.apache.ignite.examples.servicegrid;
import java.util.Collection;
import org.apache.ignite.Ignite;
import org.apache.ignite.IgniteServices;
import org.apache.ignite.Ignition;
import org.apache.ignite.examples.ExampleNodeStartup;
import org.apache.ignite.examples.ExamplesUtils;
import org.apache.ignite.lang.IgniteCallable;
import org.apache.ignite.resources.ServiceResource;
/**
* Example that demonstrates how to deploy distributed services in Ignite.
* Distributed services are especially useful when deploying singletons on the ignite,
* be that cluster-singleton, or per-node-singleton, etc...
* <p>
* To start remote nodes, you must run {@link ExampleNodeStartup} in another JVM
* which will start node with {@code examples/config/example-ignite.xml} configuration.
* <p>
* NOTE:<br/>
* Starting {@code ignite.sh} directly will not work, as distributed services
* cannot be peer-deployed and classes must be on the classpath for every node.
*/
public class ServicesExample {
/**
* Executes example.
*
* @param args Command line arguments, none required.
* @throws Exception If example execution failed.
*/
public static void main(String[] args) throws Exception {
// Mark this node as client node.
Ignition.setClientMode(true);
try (Ignite ignite = Ignition.start("examples/config/example-ignite.xml")) {
if (!ExamplesUtils.hasServerNodes(ignite))
return;
// Deploy services only on server nodes.
IgniteServices svcs = ignite.services(ignite.cluster().forServers());
try {
// Deploy cluster singleton.
svcs.deployClusterSingleton("myClusterSingletonService", new SimpleMapServiceImpl());
// Deploy node singleton.
svcs.deployNodeSingleton("myNodeSingletonService", new SimpleMapServiceImpl());
// Deploy 2 instances, regardless of number nodes.
svcs.deployMultiple("myMultiService",
new SimpleMapServiceImpl(),
2 /*total number*/,
0 /*0 for unlimited*/);
// Example for using a service proxy
// to access a remotely deployed service.
serviceProxyExample(ignite);
// Example for auto-injecting service proxy
// into remote closure execution.
serviceInjectionExample(ignite);
}
finally {
// Undeploy all services.
ignite.services().cancelAll();
}
}
}
/**
* Simple example to demonstrate service proxy invocation of a remotely deployed service.
*
* @param ignite Ignite instance.
* @throws Exception If failed.
*/
private static void serviceProxyExample(Ignite ignite) throws Exception {
System.out.println(">>>");
System.out.println(">>> Starting service proxy example.");
System.out.println(">>>");
// Get a sticky proxy for node-singleton map service.
SimpleMapService<Integer, String> mapSvc = ignite.services().serviceProxy("myNodeSingletonService",
SimpleMapService.class,
true);
int cnt = 10;
// Each service invocation will go over a proxy to some remote node.
// Since service proxy is sticky, we will always be contacting the same remote node.
for (int i = 0; i < cnt; i++)
mapSvc.put(i, Integer.toString(i));
// Get size from remotely deployed service instance.
int mapSize = mapSvc.size();
System.out.println("Map service size: " + mapSize);
if (mapSize != cnt)
throw new Exception("Invalid map size [expected=" + cnt + ", actual=" + mapSize + ']');
}
/**
* Simple example to demonstrate how to inject service proxy into distributed closures.
*
* @param ignite Ignite instance.
* @throws Exception If failed.
*/
private static void serviceInjectionExample(Ignite ignite) throws Exception {
System.out.println(">>>");
System.out.println(">>> Starting service injection example.");
System.out.println(">>>");
// Get a sticky proxy for cluster-singleton map service.
SimpleMapService<Integer, String> mapSvc = ignite.services().serviceProxy("myClusterSingletonService",
SimpleMapService.class,
true);
int cnt = 10;
// Each service invocation will go over a proxy to the remote cluster-singleton instance.
for (int i = 0; i < cnt; i++)
mapSvc.put(i, Integer.toString(i));
// Broadcast closure to every node.
final Collection<Integer> mapSizes = ignite.compute().broadcast(new SimpleClosure());
System.out.println("Closure execution result: " + mapSizes);
// Since we invoked the same cluster-singleton service instance
// from all the remote closure executions, they should all return
// the same size equal to 'cnt' value.
for (int mapSize : mapSizes)
if (mapSize != cnt)
throw new Exception("Invalid map size [expected=" + cnt + ", actual=" + mapSize + ']');
}
/**
* Simple closure to demonstrate auto-injection of the service proxy.
*/
private static class SimpleClosure implements IgniteCallable<Integer> {
/** Auto-inject service proxy. */
@ServiceResource(serviceName = "myClusterSingletonService", proxyInterface = SimpleMapService.class)
private transient SimpleMapService mapSvc;
/** {@inheritDoc} */
@Override public Integer call() throws Exception {
int mapSize = mapSvc.size();
System.out.println("Executing closure [mapSize=" + mapSize + ']');
return mapSize;
}
}
}