package co.codewizards.cloudstore.test;
import static co.codewizards.cloudstore.core.util.Util.*;
import static org.assertj.core.api.Assertions.*;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import co.codewizards.cloudstore.core.Uid;
import co.codewizards.cloudstore.core.oio.File;
import co.codewizards.cloudstore.core.oio.OioFileFactory;
import co.codewizards.cloudstore.core.repo.local.LocalRepoManager;
import co.codewizards.cloudstore.core.repo.local.LocalRepoManagerFactory;
import co.codewizards.cloudstore.core.util.ReflectionUtil;
import co.codewizards.cloudstore.local.persistence.Directory;
import co.codewizards.cloudstore.local.persistence.LocalRepository;
import co.codewizards.cloudstore.ls.client.LocalServerClient;
import co.codewizards.cloudstore.ls.core.invoke.RemoteObjectProxy;
import co.codewizards.cloudstore.ls.rest.client.LocalServerRestClient;
import co.codewizards.cloudstore.test.model.ExampleService;
import co.codewizards.cloudstore.test.model.ExampleServiceImpl;
public class LocalServerClientIT extends AbstractIT {
// private static LocalServer localServer; // LocalServer is already started by main server.
private static LocalServerClient client;
@BeforeClass
public static void beforeLocalServerClientIT() {
// localServer = new LocalServer();
// localServer.start();
final LocalServerRestClient localServerRestClient = new LocalServerRestClient() {
};
client = new LocalServerClient() {
@Override
protected LocalServerRestClient _getLocalServerRestClient() {
return localServerRestClient;
}
};
}
@AfterClass
public static void afterLocalServerClientIT() {
if (client != null) {
client.close();
client = null;
}
// localServer.stop();
}
@Test
public void invokeSimpleStaticMethod() throws Exception {
Long remoteMillis = client.invokeStatic(System.class, "currentTimeMillis");
long localMillis = System.currentTimeMillis();
assertThat(remoteMillis).isNotNull();
assertThat(localMillis - remoteMillis).isBetween(0L, 10000L);
}
@Test
public void invokeDeniedMethods() throws Exception {
try {
client.invokeStatic(System.class, "setProperty", "key1", "value1");
fail("Succeeded invoking a method that should be denied!");
} catch (SecurityException x) {
doNothing();
}
// This is denied by the explicit blacklist in AllowCloudStoreInvocationFilter (by default all classes in *our* package are allowed)
try {
client.invokeStatic(ReflectionUtil.class, "invokeStatic", System.class, "getProperty", new Object[] { "user.home" });
fail("Succeeded invoking a method that should be denied!");
} catch (SecurityException x) {
doNothing();
}
}
@Test
public void invokeConstructorAndSomeMethodsViaApi() throws Exception {
Object localRepository = client.invokeConstructor(LocalRepository.class);
assertThat(localRepository).isInstanceOf(RemoteObjectProxy.class);
byte[] privateKeyOutput = client.invoke(localRepository, "getPrivateKey");
assertThat(privateKeyOutput).isNull();
byte[] privateKeyInput = new Uid().toBytes();
client.invoke(localRepository, "setPrivateKey", privateKeyInput);
privateKeyOutput = client.invoke(localRepository, "getPrivateKey");
assertThat(privateKeyOutput).isEqualTo(privateKeyInput);
Object rootDirectoryOutput = client.invoke(localRepository, "getRoot");
Object rootDirectoryInput = client.invokeConstructor(Directory.class);
assertThat(rootDirectoryInput).isInstanceOf(RemoteObjectProxy.class);
client.invoke(localRepository, "setRoot", rootDirectoryInput);
rootDirectoryOutput = client.invoke(localRepository, "getRoot");
assertThat(rootDirectoryOutput).isInstanceOf(RemoteObjectProxy.class);
assertThat(rootDirectoryOutput).isSameAs(rootDirectoryInput);
}
@Test
public void invokeStaticMethodAndSomeMethodsViaProxy() throws Exception {
File localRootInput = newTestRepositoryLocalRoot("");
assertThat(localRootInput).isNotInstanceOf(RemoteObjectProxy.class);
File localRoot = client.invokeStatic(OioFileFactory.class, "createFile", localRootInput.getAbsolutePath());
assertThat(localRoot).isInstanceOf(File.class);
assertThat(localRoot.mkdir()).isTrue();
LocalRepoManagerFactory localRepoManagerFactory = client.invokeStatic(LocalRepoManagerFactory.Helper.class, "getInstance");
LocalRepoManager localRepoManager = localRepoManagerFactory.createLocalRepoManagerForNewRepository(localRoot);
assertThat(localRepoManager).isInstanceOf(RemoteObjectProxy.class);
Map<UUID, URL> map = localRepoManager.getRemoteRepositoryId2RemoteRootMap();
assertThat(map).isInstanceOf(RemoteObjectProxy.class);
localRepoManager.close();
}
private static class PropertyChangeListenerInvocation {
public final PropertyChangeListener listener;
public final PropertyChangeEvent event;
public PropertyChangeListenerInvocation(final PropertyChangeListener listener, final PropertyChangeEvent event) {
this.listener = listener;
this.event = event;
}
}
@Test
public void testPropertyChangeListener() throws Exception {
ExampleService exampleService = client.invokeConstructor(ExampleServiceImpl.class);
final List<PropertyChangeListenerInvocation> propertyChangeListenerInvocations = new ArrayList<>();
final boolean[] slept = new boolean[] { false };
final boolean[] sleepEnabled = new boolean[] { true };
PropertyChangeListener globalPropertyChangeListener = new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent event) {
if (sleepEnabled[0]) {
try { Thread.sleep(300_000); } catch (InterruptedException e) { }
slept[0] = true;
}
propertyChangeListenerInvocations.add(new PropertyChangeListenerInvocation(this, event));
}
};
PropertyChangeListener stringValuePropertyChangeListener = new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent event) {
// if (sleepEnabled[0])
// try { Thread.sleep(300_000); } catch (InterruptedException e) { }
propertyChangeListenerInvocations.add(new PropertyChangeListenerInvocation(this, event));
}
};
exampleService.addPropertyChangeListener(globalPropertyChangeListener);
exampleService.addPropertyChangeListener(ExampleService.PropertyEnum.stringValue, stringValuePropertyChangeListener);
assertThat(slept[0]).isFalse();
propertyChangeListenerInvocations.clear();
exampleService.setStringValue("aaa");
assertThat(propertyChangeListenerInvocations).hasSize(2);
assertThat(slept[0]).isTrue();
sleepEnabled[0] = false;
exampleService.setStringValue("bbb");
assertThat(propertyChangeListenerInvocations).hasSize(4);
exampleService.setLongValue(123);
assertThat(propertyChangeListenerInvocations).hasSize(5);
assertThat(propertyChangeListenerInvocations.get(0).listener).isSameAs(globalPropertyChangeListener);
assertThat(propertyChangeListenerInvocations.get(0).event.getOldValue()).isEqualTo(null);
assertThat(propertyChangeListenerInvocations.get(0).event.getNewValue()).isEqualTo("aaa");
assertThat(propertyChangeListenerInvocations.get(1).listener).isSameAs(stringValuePropertyChangeListener);
assertThat(propertyChangeListenerInvocations.get(1).event.getOldValue()).isEqualTo(null);
assertThat(propertyChangeListenerInvocations.get(1).event.getNewValue()).isEqualTo("aaa");
assertThat(propertyChangeListenerInvocations.get(2).listener).isSameAs(globalPropertyChangeListener);
assertThat(propertyChangeListenerInvocations.get(2).event.getOldValue()).isEqualTo("aaa");
assertThat(propertyChangeListenerInvocations.get(2).event.getNewValue()).isEqualTo("bbb");
assertThat(propertyChangeListenerInvocations.get(3).listener).isSameAs(stringValuePropertyChangeListener);
assertThat(propertyChangeListenerInvocations.get(3).event.getOldValue()).isEqualTo("aaa");
assertThat(propertyChangeListenerInvocations.get(3).event.getNewValue()).isEqualTo("bbb");
assertThat(propertyChangeListenerInvocations.get(4).listener).isSameAs(globalPropertyChangeListener);
assertThat(propertyChangeListenerInvocations.get(4).event.getOldValue()).isEqualTo(0L);
assertThat(propertyChangeListenerInvocations.get(4).event.getNewValue()).isEqualTo(123L);
}
}