blob: 13ae27abedc9ae2e12c2d830cbbbe3d1ea6de2c3 [file] [log] [blame]
/*
* Copyright (c) 2020 Kentyou.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Kentyou - initial API and implementation
*/
package org.eclipse.sensinact.gateway.core.test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.lang.reflect.Method;
import java.util.Dictionary;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
import org.eclipse.sensinact.gateway.common.constraint.Changed;
import org.eclipse.sensinact.gateway.common.constraint.Constraint;
import org.eclipse.sensinact.gateway.common.constraint.MaxLength;
import org.eclipse.sensinact.gateway.common.constraint.MinLength;
import org.eclipse.sensinact.gateway.common.execution.ErrorHandler;
import org.eclipse.sensinact.gateway.common.execution.Executable;
import org.eclipse.sensinact.gateway.common.primitive.InvalidValueException;
import org.eclipse.sensinact.gateway.common.primitive.Modifiable;
import org.eclipse.sensinact.gateway.common.props.TypedProperties;
import org.eclipse.sensinact.gateway.core.ActionResource;
import org.eclipse.sensinact.gateway.core.Attribute;
import org.eclipse.sensinact.gateway.core.DataResource;
import org.eclipse.sensinact.gateway.core.FilteringCollection;
import org.eclipse.sensinact.gateway.core.FilteringDefinition;
import org.eclipse.sensinact.gateway.core.InvalidServiceProviderException;
import org.eclipse.sensinact.gateway.core.LocationResource;
import org.eclipse.sensinact.gateway.core.Metadata;
import org.eclipse.sensinact.gateway.core.ModelInstance;
import org.eclipse.sensinact.gateway.core.PropertyResource;
import org.eclipse.sensinact.gateway.core.Resource;
import org.eclipse.sensinact.gateway.core.ResourceImpl;
import org.eclipse.sensinact.gateway.core.Service;
import org.eclipse.sensinact.gateway.core.ServiceImpl;
import org.eclipse.sensinact.gateway.core.ServiceProvider;
import org.eclipse.sensinact.gateway.core.Session;
import org.eclipse.sensinact.gateway.core.StateVariableResource;
import org.eclipse.sensinact.gateway.core.message.AbstractMidAgentCallback;
import org.eclipse.sensinact.gateway.core.message.Recipient;
import org.eclipse.sensinact.gateway.core.message.SnaErrorMessageImpl;
import org.eclipse.sensinact.gateway.core.message.SnaFilter;
import org.eclipse.sensinact.gateway.core.message.SnaLifecycleMessageImpl;
import org.eclipse.sensinact.gateway.core.message.SnaMessage;
import org.eclipse.sensinact.gateway.core.message.SnaResponseMessage;
import org.eclipse.sensinact.gateway.core.message.SnaUpdateMessageImpl;
import org.eclipse.sensinact.gateway.core.method.AccessMethod;
import org.eclipse.sensinact.gateway.core.method.AccessMethodExecutor;
import org.eclipse.sensinact.gateway.core.method.AccessMethodResponse;
import org.eclipse.sensinact.gateway.core.method.AccessMethodResponseBuilder;
import org.eclipse.sensinact.gateway.core.method.GetResponse;
import org.eclipse.sensinact.gateway.core.method.LinkedActMethod;
import org.eclipse.sensinact.gateway.core.method.Parameter;
import org.eclipse.sensinact.gateway.core.method.SetResponse;
import org.eclipse.sensinact.gateway.core.method.Shortcut;
import org.eclipse.sensinact.gateway.core.method.Signature;
import org.eclipse.sensinact.gateway.core.method.SubscribeResponse;
import org.eclipse.sensinact.gateway.core.method.trigger.Constant;
import org.eclipse.sensinact.gateway.core.security.AccessProfileOption;
import org.eclipse.sensinact.gateway.core.security.AccessTree;
import org.eclipse.sensinact.gateway.core.security.AccessTreeImpl;
import org.eclipse.sensinact.gateway.core.security.SecuredAccessException;
import org.eclipse.sensinact.gateway.datastore.api.DataStoreException;
import org.json.JSONArray;
import org.json.JSONObject;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mockito;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleException;
import org.osgi.framework.InvalidSyntaxException;
import org.skyscreamer.jsonassert.JSONAssert;
/**
* Test ResourceFactory
*/
@SuppressWarnings({ "rawtypes" })
public class TestResourceBuilder<R extends ModelInstance> {
protected TestContext testContext;
protected Dictionary<String, Object> props;
protected AccessTree tree;
private final BundleContext context = Mockito.mock(BundleContext.class);
private final Bundle bundle = Mockito.mock(Bundle.class);
@Before
public void init() throws InvalidServiceProviderException, InvalidSyntaxException, SecuredAccessException,
DataStoreException, BundleException {
try {
this.testContext = new TestContext();
this.tree = new AccessTreeImpl(testContext.getMediator()).withAccessProfile(AccessProfileOption.ALL_ANONYMOUS);
}catch(Exception e) {
e.printStackTrace();
}
}
@After
public void tearDown() {
this.testContext.stop();
}
@Test
public void testSessionMethods() throws Exception {
ServiceImpl service = this.testContext.getModelInstance().getRootElement().addService("testService");
ResourceImpl r1impl = service.addDataResource(PropertyResource.class, "TestProperty", String.class, "hello");
Session session = this.testContext.getSensiNact().getAnonymousSession();
PropertyResource r1 = r1impl.<PropertyResource>getProxy(this.tree);
// test shortcut
Assert.assertEquals("TestProperty", r1.getName());
Assert.assertEquals(Resource.Type.PROPERTY, r1.getType());
String get1 = session.get("serviceProvider", "testService", "TestProperty", DataResource.VALUE).getJSON();
String get2 = r1.get().getJSON();
JSONAssert.assertEquals(get1, get2, false);
final JSONObject changed = new JSONObject(
new Changed(Thread.currentThread().getContextClassLoader(), true).getJSON());
SubscribeResponse res = session.subscribe("serviceProvider", "testService", "TestProperty", new Recipient() {
@Override
public void callback(String callbackId, SnaMessage[] messages) throws Exception {
boolean hasChanged = ((TypedProperties<?>) messages[0]).<Boolean>get("hasChanged");
if (!hasChanged){
TestResourceBuilder.this.testContext.extraCallbackInc();
}
}
@Override
public String getJSON() {
return null;
}
}, new JSONArray() {
{
this.put(changed);
}
});
session.set("serviceProvider", "testService", "TestProperty", DataResource.VALUE, "hello");
Thread.sleep(500);
Assert.assertEquals(1, this.testContext.getExtraCallbackCount());
ResourceImpl r2impl = service.addDataResource(PropertyResource.class, "TestProperty2", String.class, null);
ResourceImpl r3impl = service.addLinkedResource("LinkedProperty", r1impl);
// test linked resource
JSONAssert.assertEquals(session.get("serviceProvider", "testService", "TestProperty", null).getResponse(),
session.get("serviceProvider", "testService", "LinkedProperty", DataResource.VALUE).getResponse(),
false);
session.set("serviceProvider", "testService", "LinkedProperty", DataResource.VALUE, "testLink");
JSONAssert.assertEquals(
session.get("serviceProvider", "testService", "TestProperty", DataResource.VALUE).getResponse(),
session.get("serviceProvider", "testService", "LinkedProperty", null).getResponse(), false);
service.addLinkedResource(LocationResource.LOCATION, this.testContext.getModelInstance().getRootElement()
.getAdminService().getResource(LocationResource.LOCATION));
ResourceImpl r4impl = service.getResource("location");
r4impl.registerExecutor(AccessMethod.Type.valueOf(AccessMethod.GET), new Class<?>[0], new String[0],
new AccessMethodExecutor() {
@Override
public Void execute(AccessMethodResponseBuilder result) throws Exception {
JSONObject jsonObject = (JSONObject) result.getAccessMethodObjectResult();
jsonObject.put("value",new StringBuilder().append(jsonObject.get("value")).append("_suffix").toString());
result.setAccessMethodObjectResult(jsonObject);
return null;
}
}, AccessMethodExecutor.ExecutionPolicy.AFTER);
String attributeValue = (String) r4impl.getAttribute("value").getValue();
Thread.sleep(250);
StringBuilder buffer = new StringBuilder();
buffer.append(attributeValue);
buffer.append("_suffix");
JSONObject message = new JSONObject(
session.get("serviceProvider", "testService", "location", DataResource.VALUE).getJSON());
assertEquals(buffer.toString(), message.getJSONObject("response").getString(DataResource.VALUE));
// test subscription
String subId = session.subscribe("serviceProvider", "testService", "TestProperty2", new Recipient() {
@Override
public void callback(String callbackId, SnaMessage[] messages) throws Exception {
TestResourceBuilder.this.testContext.callbackInc();
}
@Override
public String getJSON() {
return null;
}
}, null).getResponse().getString("subscriptionId");
session.subscribe("serviceProvider", "testService", "LinkedProperty", new Recipient() {
@Override
public void callback(String callbackId, SnaMessage[] messages) throws Exception {
TestResourceBuilder.this.testContext.linkCallbackInc();
}
@Override
public String getJSON() {
return null;
}
}, null);
JSONObject set1 = session.set("serviceProvider", "testService", "TestProperty2", null, "property3").getResponse();
Thread.sleep(250);
JSONObject set2 = session.set("serviceProvider", "testService", "TestProperty2", DataResource.VALUE, "property3").getResponse();
Assert.assertEquals(set1.get(DataResource.VALUE), set2.get(DataResource.VALUE));
JSONObject set3 = session.set("serviceProvider", "testService", "TestProperty", DataResource.VALUE, "TEST LINKED SUBSCRIPTION").getResponse();
Thread.sleep(250);
long time1 = (Long) set1.get(Metadata.TIMESTAMP);
long time2 = (Long) set2.get(Metadata.TIMESTAMP);
Thread.sleep(500);
Assert.assertTrue(time1 != time2);
assertEquals(1, this.testContext.getCallbackCount());
session.set("serviceProvider", "testService", "TestProperty2", null, "property5");
Thread.sleep(500);
assertEquals(2, this.testContext.getCallbackCount());
String filter = "/serviceProvider/testService/TestProperty2/value";
org.junit.Assert.assertEquals(1,
((MyModelInstance) this.testContext.getModelInstance()).getHandler().count(filter));
session.unsubscribe("serviceProvider", "testService", "TestProperty2", subId);
org.junit.Assert.assertEquals(0,
((MyModelInstance) this.testContext.getModelInstance()).getHandler().count(filter));
Service proxy = service.<Service>getProxy(this.tree);
SetResponse error = proxy.set("location", DataResource.VALUE, "unknown");
assertTrue(error.getStatusCode() == 403);
assertEquals(1, this.testContext.getLinkCallbackCount());
}
@Test
public void testResourceModel() throws Exception {
ServiceImpl service = this.testContext.getModelInstance().getRootElement().addService("testService");
ResourceImpl r1impl = service.addDataResource(PropertyResource.class, "TestProperty", String.class, "hello");
PropertyResource r1 = r1impl.<PropertyResource>getProxy(this.tree);
// test shortcut
Assert.assertEquals("TestProperty", r1.getName());
Assert.assertEquals(Resource.Type.PROPERTY, r1.getType());
String get1 = r1.get(DataResource.VALUE).getJSON();
String get2 = r1.get().getJSON();
JSONAssert.assertEquals(get1, get2, false);
SubscribeResponse res = r1.subscribe(new Recipient() {
@Override
public void callback(String callbackId, SnaMessage[] messages) throws Exception {
boolean hasChanged = ((TypedProperties<?>) messages[0]).<Boolean>get("hasChanged");
if (!hasChanged)
TestResourceBuilder.this.testContext.extraCallbackInc();
}
@Override
public String getJSON() {
return null;
}
}, new HashSet<Constraint>() {{
this.add(new Changed(Thread.currentThread().getContextClassLoader(), true));
}});
r1.set("hello");
Thread.sleep(500);
Assert.assertTrue("the message should have been processed even if the value has not changed",
1 == this.testContext.getExtraCallbackCount());
ResourceImpl r2impl = service.addDataResource(PropertyResource.class, "TestProperty2", String.class, null);
PropertyResource r2 = r2impl.<PropertyResource>getProxy(this.tree);
ResourceImpl r3impl = service.addLinkedResource("LinkedProperty", r1impl);
PropertyResource r3 = r3impl.<PropertyResource>getProxy(this.tree);
ResourceImpl r4impl = service.addLinkedResource(LocationResource.LOCATION, this.testContext.getModelInstance().getRootElement()
.getAdminService().getResource(LocationResource.LOCATION));
// test linked resource
JSONAssert.assertEquals(((GetResponse) r1.get()).getResponse(), ((GetResponse) r3.get()).getResponse(), false);
r1.set("testLink");
JSONAssert.assertEquals(((GetResponse) r1.get()).getResponse(), ((GetResponse) r3.get()).getResponse(), false);
r4impl.registerExecutor(AccessMethod.Type.valueOf(AccessMethod.GET), new Class<?>[0], new String[0],
new AccessMethodExecutor() {
@Override
public Void execute(AccessMethodResponseBuilder result) throws Exception {
JSONObject jsonObject = (JSONObject) result.getAccessMethodObjectResult();
jsonObject.put("value", new StringBuilder().append(jsonObject.get("value")).append("_suffix").toString());
result.setAccessMethodObjectResult(jsonObject);
return null;
}
}, AccessMethodExecutor.ExecutionPolicy.AFTER);
String attributeValue = (String) r4impl.getAttribute("value").getValue();
LocationResource r4 = r4impl.<LocationResource>getProxy(this.tree);
Thread.sleep(250);
StringBuilder buffer = new StringBuilder();
buffer.append(attributeValue);
buffer.append("_suffix");
SnaMessage message = r4.get(DataResource.VALUE);
JSONObject object = ((GetResponse) message).getResponse();
assertEquals(buffer.toString(), object.getString(DataResource.VALUE));
// test subscription
String subId = ((SubscribeResponse) r2.subscribe(new Recipient() {
@Override
public void callback(String callbackId, SnaMessage[] messages) throws Exception {
TestResourceBuilder.this.testContext.callbackInc();
}
@Override
public String getJSON() {
return null;
}
})).getSubscriptionId();
r3.subscribe(new Recipient() {
@Override
public void callback(String callbackId, SnaMessage[] messages) throws Exception {
TestResourceBuilder.this.testContext.linkCallbackInc();
}
@Override
public String getJSON() {
return null;
}
});
JSONObject set1 = r2.set("property3").getResponse();
Thread.sleep(250);
JSONObject set2 = r2.set("value", "property3").getResponse();
Assert.assertEquals(set1.get(DataResource.VALUE), set2.get(DataResource.VALUE));
JSONObject set3 = r1.set("value", "TEST LINKED SUBSCRIPTION").getResponse();
Thread.sleep(250);
long time1 = (Long) set1.get(Metadata.TIMESTAMP);
long time2 = (Long) set2.get(Metadata.TIMESTAMP);
Thread.sleep(500);
Assert.assertTrue(time1 != time2);
assertEquals(1, this.testContext.getCallbackCount());
r2.set("value", "property5").getJSON();
Thread.sleep(500);
assertEquals(2, this.testContext.getCallbackCount());
String filter = "/serviceProvider/testService/TestProperty2/value";
org.junit.Assert.assertEquals(1,
((MyModelInstance) this.testContext.getModelInstance()).getHandler().count(filter));
r2.unsubscribe(subId);
org.junit.Assert.assertEquals(0,
((MyModelInstance) this.testContext.getModelInstance()).getHandler().count(filter));
Service proxy = service.<Service>getProxy(this.tree);
SetResponse error = proxy.set("location", DataResource.VALUE, (Object)"unknown");
assertTrue(error.getStatusCode() == 403);
assertEquals(1, this.testContext.getLinkCallbackCount());
}
@Test
public void testAgent() throws Exception {
ServiceImpl service1 = this.testContext.getModelInstance().getRootElement().addService("testService");
ResourceImpl r1impl = service1.addDataResource(PropertyResource.class, "TestProperty", String.class, "hello");
ServiceImpl service2 = this.testContext.getModelInstance().getRootElement().addService("tostService");
ResourceImpl r2impl = service2.addDataResource(PropertyResource.class, "TestProperty", String.class, "hello");
// wait for the previously generated events to be consumed
Thread.sleep(1000);
SnaFilter filter = new SnaFilter(this.testContext.getMediator(), "/serviceProvider/(test).*", true, false);
filter.addHandledType(SnaMessage.Type.UPDATE);
String agentId = this.testContext.getSensiNact().registerAgent(this.testContext.getMediator(), new AbstractMidAgentCallback() {
@Override
public void doHandle(SnaUpdateMessageImpl message) {
TestResourceBuilder.this.testContext.agentCallbackInc();
// System.out.println("TestResourceBuilder.this.agentCallbackCount++");
}
}, filter);
//System.out.println("AGENT ID = " + agentId);
PropertyResource r1 = r1impl.<PropertyResource>getProxy(this.tree);
PropertyResource r2 = r2impl.<PropertyResource>getProxy(this.tree);
assertEquals(0, TestResourceBuilder.this.testContext.getAgentCallbackCount());
System.out.println(r2.set("goodbye").getJSON());
Thread.sleep(250);
assertEquals(0, TestResourceBuilder.this.testContext.getAgentCallbackCount());
System.out.println(r1.set("goodbye").getJSON());
Thread.sleep(250);
assertEquals(1, TestResourceBuilder.this.testContext.getAgentCallbackCount());
Mockito.when(this.testContext.getMediator().getContext().getProperty(Mockito.anyString()))
.thenAnswer(new Answer<Object>() {
@Override
public String answer(InvocationOnMock invocation) throws Throwable {
String parameter = (String) invocation.getArguments()[0];
if ("org.eclipse.sensinact.gateway.filter.suffix".equals(parameter)) {
return "test";
}
if ("org.eclipse.sensinact.gateway.filter.types.test".equals(parameter)) {
return "LIFECYCLE";
}
if ("org.eclipse.sensinact.gateway.filter.sender.test".equals(parameter)) {
return "/(serviceProvider)/(test).*";
}
if ("org.eclipse.sensinact.gateway.filter.pattern.test".equals(parameter)) {
return "true";
}
if ("org.eclipse.sensinact.gateway.filter.complement.test".equals(parameter)) {
return "true";
}
if ("org.eclipse.sensinact.gateway.filter.conditions.test".equals(parameter)) {
return null;
}
return null;
}
});
TestResourceBuilder.this.testContext.agentCallbackCountReset();
this.testContext.getSensiNact().registerAgent(this.testContext.getMediator(), new AbstractMidAgentCallback() {
@Override
public void doHandle(SnaLifecycleMessageImpl message) {
TestResourceBuilder.this.testContext.agentCallbackInc();
}
@Override
public void doHandle(SnaErrorMessageImpl message) {
}
@Override
public void doHandle(SnaResponseMessage message) {
}
@Override
public void doHandle(SnaUpdateMessageImpl message) {
}
@Override
public void stop() {
}
}, null);
this.testContext.getModelInstance().getRootElement().stop();
Thread.sleep(500);
// {"notification":{"lifecycle":"RESOURCE_DISAPPEARING"},"uri":"/serviceProvider/admin/location"}
// {"notification":{"lifecycle":"RESOURCE_DISAPPEARING"},"uri":"/serviceProvider/admin/icon"}
// {"notification":{"lifecycle":"RESOURCE_DISAPPEARING"},"uri":"/serviceProvider/admin/friendlyName"}
// {"notification":{"lifecycle":"RESOURCE_DISAPPEARING"},"uri":"/serviceProvider/admin/bridge"}
// {"notification":{"lifecycle":"SERVICE_DISAPPEARING"},"uri":"/serviceProvider/admin"}
// {"notification":{"lifecycle":"RESOURCE_DISAPPEARING"},"uri":"/serviceProvider/tostService/TestProperty"}
// {"notification":{"lifecycle":"SERVICE_DISAPPEARING"},"uri":"/serviceProvider/tostService"}
// {"notification":{"lifecycle":"PROVIDER_DISAPPEARING"},"uri":"/serviceProvider"}
assertEquals(8, this.testContext.getAgentCallbackCount());
}
@Test
public void testSecuredAccess() throws Exception {
ServiceImpl service = this.testContext.getModelInstance().getRootElement().addService("testService");
service.addLinkedResource(LocationResource.LOCATION, this.testContext.getModelInstance().getRootElement()
.getAdminService().getResource(LocationResource.LOCATION));
ResourceImpl r4impl = service.getResource("location");
r4impl.registerExecutor(AccessMethod.Type.valueOf(AccessMethod.GET), new Class<?>[0], new String[0],
new AccessMethodExecutor() {
@Override
public Void execute(AccessMethodResponseBuilder result) throws Exception {
JSONObject jsonObject = (JSONObject) result.getAccessMethodObjectResult();
jsonObject.put("value",
new StringBuilder().append(jsonObject.get("value")).append("_suffix").toString());
result.setAccessMethodObjectResult(jsonObject);
return null;
}
}, AccessMethodExecutor.ExecutionPolicy.AFTER);
String attributeValue = (String) r4impl.getAttribute("value").setValue("0:0");
Session session = this.testContext.getSensiNact().getAnonymousSession();
Resource r4 = session.resource("serviceProvider", "testService", "location");
Assert.assertNotNull(r4);
StringBuilder buffer = new StringBuilder();
buffer.append(attributeValue);
buffer.append("_suffix");
GetResponse response = r4.get(DataResource.VALUE);
String value = (String) response.getResponse().opt(DataResource.VALUE);
assertEquals(buffer.toString(), value);
r4 = session.resource("serviceProvider", "admin", "location");
response = r4.get(DataResource.VALUE);
value = (String) response.getResponse().opt(DataResource.VALUE);
assertFalse(buffer.toString().equals(value));
}
@Test(expected = InvalidValueException.class)
public void testConstrained() throws Exception {
ServiceImpl service = this.testContext.getModelInstance().getRootElement().addService("testService");
ResourceImpl r2impl = service.addDataResource(PropertyResource.class, "TestProperty2", String.class, null);
Executable<Void, Object> extractor = service.getResourceValueExtractor("TestProperty2");
Attribute valueAttribute = r2impl.getAttribute(DataResource.VALUE);
valueAttribute
.addMetadata(new Metadata(this.testContext.getMediator(), Metadata.CONSTRAINTS, Constraint[].class,
new Constraint[] { new MinLength(this.testContext.getMediator().getClassLoader(), 5, false),
new MaxLength(this.testContext.getMediator().getClassLoader(), 10, false)
}, Modifiable.FIXED));
try {
valueAttribute.setValue("not much");
} catch (InvalidValueException e) {
fail("should have complied constraints");
}
assertEquals("not much", extractor.execute(null));
valueAttribute.setValue("too much characters");
fail("MaxLength constraint fails");
}
@Test
public void testDynamicAdded() throws Exception {
ServiceImpl service = this.testContext.getModelInstance().getRootElement().addService("testService");
ServiceProvider proxy = this.testContext.getModelInstance().getRootElement().getProxy(this.tree);
List<Service> services = proxy.getServices();
Assert.assertEquals(2, services.size());
this.testContext.getModelInstance().getRootElement().addService("dynamicService");
services = proxy.getServices();
Assert.assertEquals(3, services.size());
service.addDataResource(PropertyResource.class, "dynamicResource", String.class, "dynamic");
assertNotNull(proxy.getService("testService").getResource("dynamicResource"));
}
@Test
public void testLinkedAction() throws Exception {
ServiceImpl service = this.testContext.getModelInstance().getRootElement().addService("testService");
ResourceImpl action = service.addActionResource("action", ActionResource.class);
final AtomicInteger counter = new AtomicInteger(0);
action.registerExecutor(new Signature(this.testContext.getMediator(),
AccessMethod.Type.valueOf(AccessMethod.ACT), new Class<?>[] { int.class }, new String[] { "count" }),
new AccessMethodExecutor() {
@Override
public Void execute(AccessMethodResponseBuilder parameter) throws Exception {
int count = (Integer) parameter.getParameter(0);
for (int i = 0; i < count; i++) {
counter.incrementAndGet();
}
return null;
}
}, AccessMethodExecutor.ExecutionPolicy.AFTER);
action.registerExecutor(
new Signature(this.testContext.getMediator(), AccessMethod.Type.valueOf(AccessMethod.ACT),
new Class<?>[] { int.class, boolean.class }, new String[] { "count", "plus" }),
new AccessMethodExecutor() {
@Override
public Void execute(AccessMethodResponseBuilder parameter) throws Exception {
int count = (Integer) parameter.getParameter(0);
boolean plus = (Boolean) parameter.getParameter(1);
if (plus) {
for (int i = 0; i < count; i++) {
counter.incrementAndGet();
}
} else {
for (int i = 0; i < count; i++) {
counter.decrementAndGet();
}
}
return null;
}
}, AccessMethodExecutor.ExecutionPolicy.AFTER);
service.addLinkedActionResource("linkedAction", action, true);
ResourceImpl emptyLinkedAction = service.addLinkedActionResource("emptyLinkedAction", action, false);
Method method = ResourceImpl.class.getDeclaredMethod("getAccessMethod", AccessMethod.Type.class);
method.setAccessible(true);
LinkedActMethod linkedActMethod = (LinkedActMethod) method.invoke(emptyLinkedAction,
AccessMethod.Type.valueOf(AccessMethod.ACT));
method = LinkedActMethod.class.getDeclaredMethod("createShortcut",
new Class<?>[] { Signature.class, Shortcut.class });
method.setAccessible(true);
method.invoke(linkedActMethod,
new Object[] {
new Signature(this.testContext.getMediator(), AccessMethod.Type.valueOf(AccessMethod.ACT),
new Class<?>[] { int.class }, new String[] { "count" }),
new Shortcut(this.testContext.getMediator(), AccessMethod.Type.valueOf(AccessMethod.ACT),
new Class<?>[0], new String[0], new HashMap<Integer, Parameter>() {
{
this.put(0, new Parameter(TestResourceBuilder.this.testContext.getMediator(),
"count", int.class, 4));
}
}) });
// securedAccess.getAnonymousSession().registered(instance);
// instance.getServiceProvider().start();
ServiceProvider proxy = (ServiceProvider) this.testContext.getModelInstance().getRootElement()
.getProxy(this.tree);
Service testService = proxy.getService("testService");
ActionResource resource = testService.<ActionResource>getResource("action");
ActionResource linkedResource = testService.<ActionResource>getResource("linkedAction");
ActionResource emptyLinkedResource = testService.<ActionResource>getResource("emptyLinkedAction");
assertEquals(0, counter.get());
resource.act(5).getJSON();
assertEquals(5, counter.get());
resource.act(4, false).getJSON();
assertEquals(1, counter.get());
linkedResource.act(2).getJSON();
assertEquals(3, counter.get());
linkedResource.act(1, false).getJSON();
assertEquals(2, counter.get());
emptyLinkedResource.act().getJSON();
assertEquals(6, counter.get());
assertEquals(emptyLinkedResource.act(2).getStatus(), AccessMethodResponse.Status.ERROR);
assertEquals(6, counter.get());
assertEquals(emptyLinkedResource.act(2, false).getStatus(), AccessMethodResponse.Status.ERROR);
assertEquals(6, counter.get());
}
@Test
public void testTrigger() throws Throwable {
ServiceImpl service = this.testContext.getModelInstance().getRootElement().addService("testService");
ResourceImpl r1impl = service.addActionResource("TestAction", ActionResource.class);
ResourceImpl r2impl = service.addDataResource(StateVariableResource.class, "TestVariable", String.class,
"untriggered");
service.addTrigger("TestAction", "TestVariable",
new Signature(this.testContext.getMediator(), AccessMethod.Type.valueOf(AccessMethod.ACT), null, null),
new Constant("triggered", false), AccessMethodExecutor.ExecutionPolicy.AFTER);
// test locked
try {
r2impl.set("triggered");
fail("Attribute should be locked");
} catch (Exception e) {
// e.printStackTrace();
}
// securedAccess.getAnonymousSession().registered(instance);
// instance.getServiceProvider().start();
// test trigger
assertEquals("untriggered", r2impl.getAttribute(DataResource.VALUE).getValue());
ActionResource proxy = (ActionResource) r1impl.getProxy(this.tree);
proxy.act();
assertEquals("triggered", r2impl.getAttribute(DataResource.VALUE).getValue());
}
@Test
public void testFiltering() throws Throwable {
ServiceImpl service = this.testContext.getModelInstance().getRootElement().addService("testService");
ResourceImpl r1impl = service.addActionResource("TestAction", ActionResource.class);
ResourceImpl r2impl = service.addDataResource(StateVariableResource.class, "TestVariable", String.class,
"untriggered");
Session s = testContext.getSensiNact().getAnonymousSession();
Thread.sleep(1000);
String obj = s.getAll(
new FilteringCollection(this.testContext.getMediator(), false, new FilteringDefinition("xfilter", "a")))
.getJSON();
JSONAssert.assertEquals(
new JSONObject("{\"providers\":" + "[{\"locXtion\":\"45.19334890078532:5.706474781036377\","
+ "\"services\":[{\"resources\":" + "[{\"type\":\"PROPERTY\",\"nXme\":\"friendlyNXme\"},"
+ "{\"type\":\"PROPERTY\",\"nXme\":\"locXtion\"},"
+ "{\"type\":\"PROPERTY\",\"nXme\":\"bridge\"}," + "{\"type\":\"PROPERTY\",\"nXme\":\"icon\"}],"
+ "\"nXme\":\"Xdmin\"}," + "{\"resources\":" + "[{\"type\":\"ACTION\",\"nXme\":\"TestAction\"},"
+ "{\"type\":\"STATE_VARIABLE\",\"nXme\":\"TestVXriXble\"}],"
+ "\"nXme\":\"testService\"}],\"nXme\":\"serviceProvider\"}],"
+ "\"filters\":[{\"definition\":\"a\",\"type\":\"xfilter\"}]"
+ ",\"statusCode\":200,\"type\":\"COMPLETE_LIST\"}"),
new JSONObject(obj), false);
}
}