Fixes in live tests

This commit is contained in:
vicglarson 2011-04-20 22:56:50 +04:00 committed by Dmitri Babaev
parent 3899ff2f99
commit d065f61b92
8 changed files with 193 additions and 200 deletions

View File

@ -1,60 +0,0 @@
package org.jclouds.openstack.nova;
import com.google.common.collect.ImmutableSet;
import org.jclouds.compute.ComputeService;
import org.jclouds.compute.ComputeServiceContext;
import org.jclouds.compute.ComputeServiceContextFactory;
import org.jclouds.compute.RunNodesException;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.Template;
import org.jclouds.compute.options.TemplateOptions;
import org.jclouds.logging.slf4j.config.SLF4JLoggingModule;
import org.jclouds.ssh.jsch.config.JschSshClientModule;
import java.util.Properties;
import java.util.Set;
import static org.jclouds.Constants.PROPERTY_ENDPOINT;
public class _NovaClient {
@SuppressWarnings("unused")
static public void main(String[] args) {
//curl -v -H "X-Auth-User:admin" -H "X-Auth-Key: d744752f-20d3-4d75-979f-f62f16033b07" http://dragon004.hw.griddynamics.net:8774/v1.0/
//curl -v -H "X-Auth-Token: c97b10659008d5a9ce91462f8c6a5c2c80439762" http://dragon004.hw.griddynamics.net:8774/v1.0/images/detail?format=json
String identity = "admin";
String credential = "d744752f-20d3-4d75-979f-f62f16033b07";
String endpoint = "http://dragon004.hw.griddynamics.net:8774";
ComputeServiceContextFactory contextFactory = new ComputeServiceContextFactory();
Properties overrides = new Properties();
overrides.setProperty(PROPERTY_ENDPOINT, endpoint);
ComputeServiceContext context = contextFactory.createContext("nova", identity, credential,
ImmutableSet.of(new JschSshClientModule(), new SLF4JLoggingModule()), overrides);
ComputeService cs = context.getComputeService();
System.out.println(cs.listImages());
System.out.println(cs.listHardwareProfiles());
System.out.println(cs.listAssignableLocations());
System.out.println(cs.listNodes());
if (false) {
TemplateOptions options = new TemplateOptions().blockUntilRunning(false);
Template template = cs.templateBuilder().imageId("95").hardwareId("2").options(options).build();
try {
Set<? extends NodeMetadata> metedata = cs.createNodesInGroup("test", 1, template);
System.out.println(metedata);
} catch (RunNodesException e) {
e.printStackTrace();
}
}
//System.out.println(cs.getNodeMetadata("64"));
//cs.destroyNode("64");
context.close();
}
}

View File

@ -21,7 +21,6 @@ package org.jclouds.openstack.nova.live;
import com.google.common.base.Predicate;
import com.google.common.collect.ImmutableMap;
import org.jclouds.Constants;
import org.jclouds.http.HttpResponseException;
import org.jclouds.net.IPSocket;
import org.jclouds.openstack.nova.NovaClient;
@ -31,12 +30,8 @@ import org.jclouds.ssh.SshClient;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.Test;
import java.io.IOException;
import java.util.Map;
import java.util.Properties;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.jclouds.openstack.nova.PropertyHelper.overridePropertyFromSystemProperty;
import static org.jclouds.openstack.nova.options.CreateServerOptions.Builder.withFile;
/**
@ -58,39 +53,6 @@ public class DeleteServersInVariousStatesLiveTest {
Map<String, String> metadata = ImmutableMap.of("jclouds", "rackspace");
Server server = null;
protected Properties setupProperties() throws IOException {
Properties overrides = new Properties();
overrides.load(this.getClass().getResourceAsStream("/test.properties"));
overridePropertyFromSystemProperty(overrides, "test." + provider + ".endpoint");
overridePropertyFromSystemProperty(overrides, "test." + provider + ".apiversion");
overridePropertyFromSystemProperty(overrides, "test." + provider + ".identity");
overridePropertyFromSystemProperty(overrides, "test." + provider + ".credential");
overridePropertyFromSystemProperty(overrides, "test.initializer");
overrides.setProperty(Constants.PROPERTY_TRUST_ALL_CERTS, "true");
overrides.setProperty(Constants.PROPERTY_RELAX_HOSTNAME, "true");
return overrides;
}
protected void setupCredentials(Properties properties) {
identity = checkNotNull(properties.getProperty("test." + provider + ".identity"), "test." + provider + ".identity");
credential = checkNotNull(properties.getProperty("test." + provider + ".credential"), "test." + provider
+ ".credential");
endpoint = properties.getProperty("test." + provider + ".endpoint");
apiversion = properties.getProperty("test." + provider + ".apiversion");
}
protected void updateProperties(final Properties properties) {
properties.setProperty(provider + ".identity", identity);
properties.setProperty(provider + ".credential", credential);
if (endpoint != null)
properties.setProperty(provider + ".endpoint", endpoint);
if (apiversion != null)
properties.setProperty(provider + ".apiversion", apiversion);
}
@Test(expectedExceptions = HttpResponseException.class, expectedExceptionsMessageRegExp = ".*Internal Server Error.*")
public void testCreateServerWithUnknownImage() throws Exception {
try {

View File

@ -17,7 +17,7 @@
* ====================================================================
*/
package org.jclouds.openstack.nova;
package org.jclouds.openstack.nova.live;
import com.google.common.base.Predicate;
import com.google.common.collect.ImmutableMap;
@ -30,6 +30,7 @@ import org.jclouds.http.HttpResponseException;
import org.jclouds.io.Payload;
import org.jclouds.logging.slf4j.config.SLF4JLoggingModule;
import org.jclouds.net.IPSocket;
import org.jclouds.openstack.nova.NovaClient;
import org.jclouds.openstack.nova.domain.*;
import org.jclouds.openstack.nova.options.RebuildServerOptions;
import org.jclouds.predicates.RetryablePredicate;
@ -49,7 +50,7 @@ import java.util.Properties;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import static org.jclouds.openstack.nova.PropertyHelper.*;
import static org.jclouds.openstack.nova.live.PropertyHelper.*;
import static org.jclouds.openstack.nova.options.CreateServerOptions.Builder.withFile;
import static org.jclouds.openstack.nova.options.ListOptions.Builder.withDetails;
import static org.testng.Assert.*;

View File

@ -16,7 +16,7 @@
* limitations under the License.
* ====================================================================
*/
package org.jclouds.openstack.nova.compute;
package org.jclouds.openstack.nova.live;
import com.google.common.base.Function;
import com.google.common.base.Predicate;
@ -31,6 +31,7 @@ import org.jclouds.compute.options.TemplateOptions;
import org.jclouds.domain.Credentials;
import org.jclouds.domain.Location;
import org.jclouds.domain.LocationScope;
import org.jclouds.http.handlers.BackoffLimitedRetryHandler;
import org.jclouds.logging.slf4j.config.SLF4JLoggingModule;
import org.jclouds.net.IPSocket;
import org.jclouds.openstack.nova.NovaAsyncClient;
@ -43,12 +44,14 @@ import org.jclouds.rest.RestContextFactory;
import org.jclouds.scriptbuilder.domain.Statements;
import org.jclouds.ssh.SshClient;
import org.jclouds.ssh.SshException;
import org.jclouds.ssh.jsch.JschSshClient;
import org.jclouds.ssh.jsch.config.JschSshClientModule;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeGroups;
import org.testng.annotations.Test;
import java.io.IOException;
import java.net.URISyntaxException;
import java.util.*;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
@ -69,8 +72,8 @@ import static org.jclouds.compute.options.TemplateOptions.Builder.overrideCreden
import static org.jclouds.compute.predicates.NodePredicates.*;
import static org.jclouds.compute.predicates.NodePredicates.all;
import static org.jclouds.compute.util.ComputeServiceUtils.getCores;
import static org.jclouds.openstack.nova.PropertyHelper.overridePropertyFromSystemProperty;
import static org.jclouds.openstack.nova.PropertyHelper.setupKeyPair;
import static org.jclouds.openstack.nova.live.PropertyHelper.overridePropertyFromSystemProperty;
import static org.jclouds.openstack.nova.live.PropertyHelper.setupKeyPair;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
@ -188,6 +191,7 @@ public class NovaComputeServiceLiveTest {
protected void checkNodes(Iterable<? extends NodeMetadata> nodes, String tag) throws IOException {
_checkNodes(nodes, tag);
for (NodeMetadata node : nodes) {
assertEquals(node.getLocation().getScope(), LocationScope.HOST);
}
@ -202,12 +206,12 @@ public class NovaComputeServiceLiveTest {
Credentials fromStore = context.getCredentialStore().get("node#" + node.getId());
assertEquals(fromStore, node.getCredentials());
assert node.getPublicAddresses().size() >= 1 || node.getPrivateAddresses().size() >= 1 : "no ips in" + node;
assertNotNull(node.getCredentials());
if (node.getCredentials().identity != null) {
assertNotNull(node.getCredentials().identity);
assertNotNull(node.getCredentials().credential);
sshPing(node);
}
// assertNotNull(node.getCredentials());
// if (node.getCredentials().identity != null) {
// assertNotNull(node.getCredentials().identity);
// assertNotNull(node.getCredentials().credential);
// doCheckJavaIsInstalledViaSsh(node);
// }
}
}
@ -219,11 +223,6 @@ public class NovaComputeServiceLiveTest {
context = new ComputeServiceContextFactory(setupRestProperties()).createContext(provider, "MOMMA", "MIA", ImmutableSet
.<Module>of(new SLF4JLoggingModule()), overrides);
context.getComputeService().listNodes();
} catch (AuthorizationException e) {
throw e;
} catch (RuntimeException e) {
e.printStackTrace();
throw e;
} finally {
if (context != null)
context.close();
@ -247,41 +246,83 @@ public class NovaComputeServiceLiveTest {
// since surefire and eclipse don't otherwise guarantee the order, we are
// starting this one alphabetically before create2nodes..
private String awaitForPublicAddressAssigned(String nodeId) throws InterruptedException {
while (true) {
Set<String> addresses = computeService.getNodeMetadata(nodeId).getPublicAddresses();
System.out.println(addresses);
if (addresses != null)
if (!addresses.isEmpty()) return addresses.iterator().next();
Thread.sleep(1000);
}
}
private void awaitForSshPort(String address, Credentials credentials) throws URISyntaxException {
IPSocket socket = new IPSocket(address, 22);
JschSshClient ssh = new JschSshClient(
new BackoffLimitedRetryHandler(), socket, 10000, credentials.identity, null, credentials.credential.getBytes());
while (true) {
try {
System.out.println("ping: " + socket);
ssh.connect();
return;
} catch (SshException ignore) {
}
}
}
@Test(enabled = true)
public void testAScriptExecutionAfterBootWithBasicTemplate() throws Exception {
String group = this.group + "r";
try {
computeService.destroyNodesMatching(inGroup(group));
} catch (Exception e) {
}
Template template = getDefaultTemplateBuilder().options(
computeService.templateOptions()
.overrideCredentialsWith(new Credentials("root", keyPair.get("private")))
.blockUntilRunning(true))
.build();
Template template = getDefaultTemplateBuilder().options(computeService.templateOptions().blockOnPort(22, 120)).build();
try {
Set<? extends NodeMetadata> nodes = computeService.createNodesInGroup(group, 1, template);
Credentials good = nodes.iterator().next().getCredentials();
assert good.identity != null : nodes;
assert good.credential != null : nodes;
System.out.println("==================================================");
System.out.println("================ Created ===================");
String address = awaitForPublicAddressAssigned(get(nodes, nodes.size() - 1).getId());
awaitForSshPort(address, new Credentials("root", keyPair.get("private")));
OperatingSystem os = get(nodes, 0).getOperatingSystem();
try {
Map<? extends NodeMetadata, ExecResponse> responses = runScriptWithCreds(group, os, new Credentials(
good.identity, "romeo"));
Map<? extends NodeMetadata, ExecResponse> responses = runJavaInstallationScriptWithCreds(group, os, new Credentials(
"root", "romeo"));
assert false : "shouldn't pass with a bad password\n" + responses;
} catch (RunScriptOnNodesException e) {
assert getRootCause(e).getMessage().contains("Auth fail") : e;
} catch (RunScriptOnNodesException ignore) {
if (!getRootCause(ignore).getMessage().contains("Auth fail")) throw ignore;
}
System.out.println("==================================================");
System.out.println("================ Auth failed ===================");
for (Map.Entry<? extends NodeMetadata, ExecResponse> response : computeService.runScriptOnNodesMatching(
runningInGroup(group), Statements.exec("echo hello"),
overrideCredentialsWith(good).wrapInInitScript(false).runAsRoot(false)).entrySet())
overrideCredentialsWith(new Credentials("root", keyPair.get("private"))).wrapInInitScript(false).runAsRoot(false)).entrySet())
assert response.getValue().getOutput().trim().equals("hello") : response.getKey() + ": "
+ response.getValue();
runScriptWithCreds(group, os, good);
System.out.println("==================================================");
System.out.println("================ Script ===================");
//TODO runJavaInstallationScriptWithCreds(group, os, new Credentials("root", keyPair.get("private")));
//no response? if os is null (ZYPPER)
checkNodes(nodes, group);
Credentials good = nodes.iterator().next().getCredentials();
//TODO check good is being private key .overrideCredentialsWith
//TODO test for .blockOnPort
} finally {
computeService.destroyNodesMatching(inGroup(group));
}
@ -374,14 +415,11 @@ public class NovaComputeServiceLiveTest {
assert (context.getCredentialStore().get("node#" + node.getId()) != null) : "credentials for " + node.getId();
}
protected Map<? extends NodeMetadata, ExecResponse> runScriptWithCreds(final String group, OperatingSystem os,
protected Map<? extends NodeMetadata, ExecResponse> runJavaInstallationScriptWithCreds(final String group, OperatingSystem os,
Credentials creds) throws RunScriptOnNodesException {
try {
return computeService.runScriptOnNodesMatching(runningInGroup(group), buildScript(os), overrideCredentialsWith(creds)
.nameTask("runScriptWithCreds"));
} catch (SshException e) {
throw e;
}
.nameTask("runJavaInstallationScriptWithCreds"));
}
@ -506,7 +544,7 @@ public class NovaComputeServiceLiveTest {
}
template = getDefaultTemplateBuilder().options(blockOnComplete(false).blockOnPort(8080, 600).inboundPorts(22, 8080))
template = getDefaultTemplateBuilder().options(blockOnComplete(false).inboundPorts(22, 8080))
.build();
// note this is a dependency on the template resolution
@ -636,22 +674,9 @@ public class NovaComputeServiceLiveTest {
assert getCores(fastest) >= getCores(smallest) : String.format("%d ! >= %d", fastest, smallest);
}
private void sshPing(NodeMetadata node) throws IOException {
for (int i = 0; i < 5; i++) {// retry loop TODO replace with predicate.
try {
doCheckJavaIsInstalledViaSsh(node);
return;
} catch (SshException e) {
try {
Thread.sleep(10 * 1000);
} catch (InterruptedException e1) {
}
continue;
}
}
}
protected void doCheckJavaIsInstalledViaSsh(NodeMetadata node) throws IOException {
SshClient ssh = context.utils().sshForNode().apply(node);
try {
ssh.connect();

View File

@ -1,4 +1,4 @@
package org.jclouds.openstack.nova;
package org.jclouds.openstack.nova.live;
import com.google.common.base.Charsets;
import com.google.common.collect.ImmutableMap;
@ -46,7 +46,7 @@ public class PropertyHelper {
properties.setProperty(provider + ".identity", properties.getProperty("test." + provider + ".identity"));
properties.setProperty(provider + ".credential", properties.getProperty("test." + provider + ".credential"));
properties.setProperty(provider + ".endpoint", properties.getProperty("test." + provider + ".endpoint"));
properties.setProperty(provider + ".apiversion", "test." + provider + ".apiversion");
properties.setProperty(provider + ".apiversion", properties.getProperty("test." + provider + ".apiversion"));
properties.setProperty(Constants.PROPERTY_TRUST_ALL_CERTS, "true");
properties.setProperty(Constants.PROPERTY_RELAX_HOSTNAME, "true");
return properties;

View File

@ -24,7 +24,6 @@ import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.inject.Injector;
import com.google.inject.Module;
import org.jclouds.Constants;
import org.jclouds.http.HttpResponseException;
import org.jclouds.logging.slf4j.config.SLF4JLoggingModule;
import org.jclouds.net.IPSocket;
@ -37,7 +36,7 @@ import org.jclouds.rest.RestContextFactory;
import org.jclouds.ssh.SshClient;
import org.jclouds.ssh.jsch.config.JschSshClientModule;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeGroups;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;
import java.io.IOException;
@ -45,8 +44,7 @@ import java.util.Map;
import java.util.Properties;
import java.util.concurrent.TimeUnit;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.jclouds.openstack.nova.PropertyHelper.overridePropertyFromSystemProperty;
import static org.jclouds.openstack.nova.live.PropertyHelper.*;
import static org.jclouds.openstack.nova.options.CreateServerOptions.Builder.withFile;
/**
@ -60,55 +58,17 @@ public class ServerCreateLiveTest {
protected SshClient.Factory sshFactory;
private Predicate<IPSocket> socketTester;
protected String provider = "nova";
protected String identity;
protected String credential;
protected String endpoint;
protected String apiversion;
Map<String, String> metadata = ImmutableMap.of("jclouds", "rackspace");
Server server = null;
Map<String, String> keyPair;
protected Properties setupProperties() throws IOException {
Properties overrides = new Properties();
overrides.load(this.getClass().getResourceAsStream("/test.properties"));
overridePropertyFromSystemProperty(overrides, "test." + provider + ".endpoint");
overridePropertyFromSystemProperty(overrides, "test." + provider + ".apiversion");
overridePropertyFromSystemProperty(overrides, "test." + provider + ".identity");
overridePropertyFromSystemProperty(overrides, "test." + provider + ".credential");
overridePropertyFromSystemProperty(overrides, "test.initializer");
overrides.setProperty(Constants.PROPERTY_TRUST_ALL_CERTS, "true");
overrides.setProperty(Constants.PROPERTY_RELAX_HOSTNAME, "true");
return overrides;
}
protected void setupCredentials(Properties properties) {
identity = checkNotNull(properties.getProperty("test." + provider + ".identity"), "test." + provider + ".identity");
credential = checkNotNull(properties.getProperty("test." + provider + ".credential"), "test." + provider
+ ".credential");
endpoint = properties.getProperty("test." + provider + ".endpoint");
apiversion = properties.getProperty("test." + provider + ".apiversion");
}
protected void updateProperties(final Properties properties) {
properties.setProperty(provider + ".identity", identity);
properties.setProperty(provider + ".credential", credential);
if (endpoint != null)
properties.setProperty(provider + ".endpoint", endpoint);
if (apiversion != null)
properties.setProperty(provider + ".apiversion", apiversion);
}
@BeforeGroups(groups = {"live"})
@BeforeTest
public void setupClient() throws IOException {
Properties overrides = setupProperties();
setupCredentials(overrides);
updateProperties(overrides);
Properties properties = setupOverrides(setupProperties(this.getClass()));
Injector injector = new RestContextFactory().createContextBuilder(provider, identity, credential,
ImmutableSet.<Module>of(new SLF4JLoggingModule(), new JschSshClientModule()), overrides)
Injector injector = new RestContextFactory().createContextBuilder(provider,
ImmutableSet.<Module>of(new SLF4JLoggingModule(), new JschSshClientModule()), properties)
.buildInjector();
client = injector.getInstance(NovaClient.class);
@ -117,6 +77,8 @@ public class ServerCreateLiveTest {
SocketOpen socketOpen = injector.getInstance(SocketOpen.class);
socketTester = new RetryablePredicate<IPSocket>(socketOpen, 120, 1, TimeUnit.SECONDS);
injector.injectMembers(socketOpen); // add logger
keyPair = setupKeyPair(properties);
}
@Test(expectedExceptions = HttpResponseException.class, expectedExceptionsMessageRegExp = ".*Internal Server Error.*")

View File

@ -0,0 +1,54 @@
package org.jclouds.openstack.nova.live.nonmaven;
import com.google.common.collect.ImmutableSet;
import org.jclouds.compute.ComputeService;
import org.jclouds.compute.ComputeServiceContext;
import org.jclouds.compute.ComputeServiceContextFactory;
import org.jclouds.compute.RunNodesException;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.Template;
import org.jclouds.compute.options.TemplateOptions;
import org.jclouds.logging.slf4j.config.SLF4JLoggingModule;
import org.jclouds.ssh.jsch.config.JschSshClientModule;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;
import java.io.IOException;
import java.util.Properties;
import java.util.Set;
import static org.jclouds.openstack.nova.live.PropertyHelper.setupOverrides;
import static org.jclouds.openstack.nova.live.PropertyHelper.setupProperties;
public class SimpleCreateServerCheck {
private ComputeServiceContextFactory contextFactory;
private ComputeServiceContext context;
@BeforeTest
public void setupClient() throws IOException {
contextFactory = new ComputeServiceContextFactory();
Properties properties = setupOverrides(setupProperties(this.getClass()));
context = contextFactory.createContext("nova",
ImmutableSet.of(new JschSshClientModule(), new SLF4JLoggingModule()), properties);
}
@Test
public void testCreateServer() throws RunNodesException {
ComputeService cs = context.getComputeService();
TemplateOptions options = new TemplateOptions().blockUntilRunning(false);
Template template = cs.templateBuilder().imageId("95").hardwareId("2").options(options).build();
Set<? extends NodeMetadata> metedata = cs.createNodesInGroup("test", 1, template);
System.out.println(metedata);
}
@AfterTest
public void after() {
context.close();
}
//curl -v -H "X-Auth-User:admin" -H "X-Auth-Key: d744752f-20d3-4d75-979f-f62f16033b07" http://dragon004.hw.griddynamics.net:8774/v1.0/
//curl -v -H "X-Auth-Token: c97b10659008d5a9ce91462f8c6a5c2c80439762" http://dragon004.hw.griddynamics.net:8774/v1.0/images/detail?format=json
}

View File

@ -0,0 +1,49 @@
package org.jclouds.openstack.nova.live.nonmaven;
import com.google.common.collect.ImmutableSet;
import org.jclouds.compute.ComputeService;
import org.jclouds.compute.ComputeServiceContext;
import org.jclouds.compute.ComputeServiceContextFactory;
import org.jclouds.logging.slf4j.config.SLF4JLoggingModule;
import org.jclouds.ssh.jsch.config.JschSshClientModule;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;
import java.io.IOException;
import java.util.Properties;
import static org.jclouds.openstack.nova.live.PropertyHelper.setupOverrides;
import static org.jclouds.openstack.nova.live.PropertyHelper.setupProperties;
public class SimpleListCheck {
private ComputeServiceContextFactory contextFactory;
private ComputeServiceContext context;
@BeforeTest
public void setupClient() throws IOException {
contextFactory = new ComputeServiceContextFactory();
Properties properties = setupOverrides(setupProperties(this.getClass()));
context = contextFactory.createContext("nova",
ImmutableSet.of(new JschSshClientModule(), new SLF4JLoggingModule()), properties);
}
@Test
public void testLists() {
ComputeService cs = context.getComputeService();
System.out.println(cs.listImages());
System.out.println(cs.listHardwareProfiles());
System.out.println(cs.listAssignableLocations());
System.out.println(cs.listNodes());
}
@AfterTest
public void after() {
context.close();
}
//curl -v -H "X-Auth-User:admin" -H "X-Auth-Key: d744752f-20d3-4d75-979f-f62f16033b07" http://dragon004.hw.griddynamics.net:8774/v1.0/
//curl -v -H "X-Auth-Token: c97b10659008d5a9ce91462f8c6a5c2c80439762" http://dragon004.hw.griddynamics.net:8774/v1.0/images/detail?format=json
}