blob: 9d2fad016e4898dded6ace2b0ced978f4f8f370b [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.misc.deployment;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import org.apache.ignite.Ignite;
import org.apache.ignite.IgniteCompute;
import org.apache.ignite.Ignition;
import org.apache.ignite.compute.ComputeJob;
import org.apache.ignite.compute.ComputeJobAdapter;
import org.apache.ignite.compute.ComputeJobResult;
import org.apache.ignite.compute.ComputeTask;
import org.apache.ignite.compute.ComputeTaskName;
import org.apache.ignite.compute.ComputeTaskSplitAdapter;
import org.apache.ignite.examples.ExampleNodeStartup;
import org.jetbrains.annotations.Nullable;
/**
* Demonstrates how to explicitly deploy a task. Note that
* it is very rare when you would need such functionality as tasks are
* auto-deployed on demand first time you execute them. So in most cases
* you would just apply any of the {@code Ignite.execute(...)} methods directly.
* However, sometimes a task is not in local class path, so you may not even
* know the code it will execute, but you still need to execute it. For example,
* you have two independent components in the system, and one loads the task
* classes from some external source and deploys it; then another component
* can execute it just knowing the name of the task.
* <p>
* Also note that for simplicity of the example, the task we execute is
* in system classpath, so even in this case the deployment step is unnecessary.
* <p>
* Remote nodes should always be started with special configuration file which
* enables P2P class loading: {@code 'ignite.{sh|bat} examples/config/example-ignite.xml'}.
* <p>
* Alternatively you can run {@link ExampleNodeStartup} in another JVM which will
* start node with {@code examples/config/example-ignite.xml} configuration.
*/
public final class DeploymentExample {
/** Name of the deployed task. */
static final String TASK_NAME = "ExampleTask";
/**
* Executes example.
*
* @param args Command line arguments, none required.
* @throws Exception If example execution failed.
*/
public static void main(String[] args) throws Exception {
try (Ignite ignite = Ignition.start("examples/config/example-ignite.xml")) {
System.out.println();
System.out.println(">>> Deployment example started.");
// This task will be deployed on local node and then peer-loaded
// onto remote nodes on demand. For this example this task is
// available on the classpath, however in real life that may not
// always be the case. In those cases you should use explicit
// 'IgniteCompute.localDeployTask(Class, ClassLoader) apply and
// then use 'IgniteCompute.execute(String, Object)' method
// passing your task name as first parameter.
ignite.compute().localDeployTask(ExampleTask.class, ExampleTask.class.getClassLoader());
for (Map.Entry<String, Class<? extends ComputeTask<?, ?>>> e : ignite.compute().localTasks().entrySet())
System.out.println(">>> Found locally deployed task [alias=" + e.getKey() + ", taskCls=" + e.getValue());
// Execute the task passing its name as a parameter. The system will find
// the deployed task by its name and execute it.
ignite.compute().execute(TASK_NAME, null);
// Execute the task passing class name as a parameter. The system will find
// the deployed task by its class name and execute it.
// g.compute().execute(ExampleTask.class.getName(), null).get();
// Undeploy task
ignite.compute().undeployTask(TASK_NAME);
System.out.println();
System.out.println(">>> Finished executing Ignite Direct Deployment Example.");
System.out.println(">>> Check participating nodes output.");
}
}
/**
* Example task used to demonstrate direct task deployment through API.
* For this example this task as available on the classpath, however
* in real life that may not always be the case. In those cases
* you should use explicit {@link IgniteCompute#localDeployTask(Class, ClassLoader)} apply and
* then use {@link IgniteCompute#execute(String, Object)}
* method passing your task name as first parameter.
* <p>
* Note that this task specifies explicit task name. Task name is optional
* and is added here for demonstration purpose. If not provided, it will
* default to the task class name.
*/
@ComputeTaskName(TASK_NAME)
public static class ExampleTask extends ComputeTaskSplitAdapter<String, Object> {
/** {@inheritDoc} */
@Override protected Collection<? extends ComputeJob> split(int clusterSize, String arg) {
Collection<ComputeJob> jobs = new ArrayList<>(clusterSize);
for (int i = 0; i < clusterSize; i++) {
jobs.add(new ComputeJobAdapter() {
@Nullable @Override public Serializable execute() {
System.out.println(">>> Executing deployment example job on this node.");
// This job does not return any result.
return null;
}
});
}
return jobs;
}
/** {@inheritDoc} */
@Override public Object reduce(List<ComputeJobResult> results) {
return null;
}
}
}