blob: 7db8ae1f293e7791222ae09159019fb5cd471eb7 [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.platform;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.UUID;
import org.apache.ignite.Ignite;
import org.apache.ignite.IgniteException;
import org.apache.ignite.Ignition;
import org.apache.ignite.binary.BinaryObjectException;
import org.apache.ignite.binary.BinaryReader;
import org.apache.ignite.binary.BinaryWriter;
import org.apache.ignite.binary.Binarylizable;
import org.apache.ignite.client.IgniteClient;
import org.apache.ignite.cluster.ClusterNode;
import org.apache.ignite.compute.ComputeJob;
import org.apache.ignite.compute.ComputeJobAdapter;
import org.apache.ignite.compute.ComputeJobResult;
import org.apache.ignite.compute.ComputeTaskAdapter;
import org.apache.ignite.configuration.ClientConfiguration;
import org.apache.ignite.internal.processors.odbc.ClientListenerProcessor;
import org.apache.ignite.internal.util.typedef.F;
import org.apache.ignite.resources.IgniteInstanceResource;
import org.apache.ignite.services.ServiceCallContext;
import org.apache.ignite.services.ServiceDescriptor;
import org.jetbrains.annotations.Nullable;
/**
* Abstract task to test platform service.
*/
public abstract class AbstractPlatformServiceCallTask extends ComputeTaskAdapter<Object[], Object> {
/** */
@SuppressWarnings("unused")
@IgniteInstanceResource
private transient Ignite ignite;
/** {@inheritDoc} */
@Override public Map<? extends ComputeJob, ClusterNode> map(List<ClusterNode> subgrid, @Nullable Object[] arg)
throws IgniteException {
assert arg.length == 2;
String srvcName = (String)arg[0];
boolean loc = (Boolean)arg[1];
Optional<ServiceDescriptor> desc = ignite.services().serviceDescriptors().stream()
.filter(d -> d.name().equals(srvcName)).findAny();
assert desc.isPresent();
ClusterNode node;
Set<UUID> srvTop = desc.get().topologySnapshot().keySet();
if (loc) {
UUID nodeId = F.rand(srvTop);
node = ignite.cluster().node(nodeId);
}
else {
node = ignite.cluster().nodes().stream().filter(n -> !srvTop.contains(n.id())).findAny().orElse(null);
assert node != null;
}
return Collections.singletonMap(createJob(srvcName), node);
}
/** {@inheritDoc} */
@Override public Object reduce(List<ComputeJobResult> results) throws IgniteException {
return results.get(0).getData();
}
/**
* Create task job.
*
* @param svcName Service name
* @return Instance of task job.
*/
abstract ComputeJobAdapter createJob(String svcName);
/** */
protected abstract static class AbstractServiceCallJob extends ComputeJobAdapter {
/** */
@SuppressWarnings("unused")
@IgniteInstanceResource
protected transient Ignite ignite;
/** */
protected final String srvcName;
/**
* @param srvcName Service name.
*/
protected AbstractServiceCallJob(String srvcName) {
assert srvcName != null;
this.srvcName = srvcName;
}
/** {@inheritDoc} */
@Override public Object execute() throws IgniteException {
try {
runTest();
return null;
}
catch (Exception e) {
throw new IgniteException(e);
}
}
/**
* Gets service proxy.
*/
TestPlatformService serviceProxy() {
ServiceCallContext callCtx = ServiceCallContext.builder().put("attr", "value").build();
return ignite.services().serviceProxy(srvcName, TestPlatformService.class, false, callCtx, 0);
}
/**
* Test method to call platform service.
*/
abstract void runTest();
/**
* Start thin client connected to current ignite instance.
*/
IgniteClient startClient() {
ClusterNode node = ignite.cluster().localNode();
String addr = F.first(node.addresses()) + ":" + node.attribute(ClientListenerProcessor.CLIENT_LISTENER_PORT);
return Ignition.startClient(new ClientConfiguration()
.setAddresses(addr)
.setBinaryConfiguration(ignite.configuration().getBinaryConfiguration())
);
}
}
/** */
protected static void assertEquals(Object exp, Object res) throws IgniteException {
if ((exp != null && !exp.equals(res)) || (res != null && !res.equals(exp)))
throw new IgniteException(String.format("Expected equals to %s, got %s", exp, res));
}
/** */
protected static void assertTrue(boolean res) {
assertEquals(true, res);
}
/** */
public interface TestPlatformService {
/** */
@PlatformServiceMethod("get_NodeId")
UUID getNodeId();
/** */
@PlatformServiceMethod("get_GuidProp")
UUID getGuidProp();
/** */
@PlatformServiceMethod("set_GuidProp")
void setGuidProp(UUID val);
/** */
@PlatformServiceMethod("get_ValueProp")
TestValue getValueProp();
/** */
@PlatformServiceMethod("set_ValueProp")
void setValueProp(TestValue val);
/** */
@PlatformServiceMethod("ErrorMethod")
void errorMethod();
/** */
@PlatformServiceMethod("AddOneToEach")
TestValue[] addOneToEach(TestValue[] col);
/** */
@PlatformServiceMethod("AddOneToEachCollection")
Collection<TestValue> addOneToEachCollection(Collection<TestValue> col);
/** */
@PlatformServiceMethod("AddOneToEachDictionary")
Map<TestKey, TestValue> addOneToEachDictionary(Map<TestKey, TestValue> dict);
/** */
@PlatformServiceMethod("AddOne")
BinarizableTestValue addOne(BinarizableTestValue val);
/** */
@PlatformServiceMethod("ContextAttribute")
String contextAttribute(String name);
/** */
@PlatformServiceMethod("Intercepted")
int intercepted(int val);
}
/** */
public static class TestKey {
/** */
private final int id;
/** */
public TestKey(int id) {
this.id = id;
}
/** */
public int id() {
return id;
}
/** {@inheritDoc} */
@Override public boolean equals(Object o) {
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
return id == ((TestKey)o).id;
}
/** {@inheritDoc} */
@Override public int hashCode() {
return Objects.hash(id);
}
}
/** */
public static class TestValue {
/** */
protected int id;
/** */
protected String name;
/** */
public TestValue(int id, String name) {
this.id = id;
this.name = name;
}
/** */
public int id() {
return id;
}
/** */
public String name() {
return name;
}
/** {@inheritDoc} */
@Override public boolean equals(Object o) {
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
TestValue val = (TestValue)o;
return id == val.id && Objects.equals(name, val.name);
}
/** {@inheritDoc} */
@Override public int hashCode() {
return Objects.hash(id, name);
}
}
/** */
public static class BinarizableTestValue extends TestValue implements Binarylizable {
/** */
public BinarizableTestValue(int id, String name) {
super(id, name);
}
/** {@inheritDoc} */
@Override public void writeBinary(BinaryWriter writer) throws BinaryObjectException {
writer.writeInt("id", id);
writer.writeString("name", name);
}
/** {@inheritDoc} */
@Override public void readBinary(BinaryReader reader) throws BinaryObjectException {
id = reader.readInt("id");
name = reader.readString("name");
}
}
}