Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,17 @@
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;

import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.utils.nio.TrustAllManager;
import com.google.gson.JsonElement;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpResponse;
Expand Down Expand Up @@ -75,14 +78,15 @@
private boolean ignoreSsl;
private int redfishRequestMaxRetries;

private final static String SYSTEMS_URL_PATH = "redfish/v1/Systems/";
private final static String COMPUTER_SYSTEM_RESET_URL_PATH = "/Actions/ComputerSystem.Reset";
private final static String SYSTEMS_URL_PATH = "redfish/v1/Systems";
private final static String COMPUTER_SYSTEM_RESET_URL_PATH = "Actions/ComputerSystem.Reset";
private final static String REDFISH_RESET_TYPE = "ResetType";
private final static String POWER_STATE = "PowerState";
private final static String APPLICATION_JSON = "application/json";
private final static String ACCEPT = "accept";
private final static String ODATA_ID = "@odata.id";
private final static String MEMBERS = "Members";
private final static String LINKS = "Links";
private final static String EXPECTED_HTTP_STATUS = "2XX";
private final static int WAIT_FOR_REQUEST_RETRY = 2;

Expand Down Expand Up @@ -265,12 +269,12 @@
if (StringUtils.isBlank(resourceId)) {
throw new RedfishException(String.format("Command '%s' requires a valid resource ID '%s'.", cmd, resourceId));
}
return String.format("%s%s", SYSTEMS_URL_PATH, resourceId);
return String.format("%s/%s", SYSTEMS_URL_PATH, resourceId);
case ComputerSystemReset:
if (StringUtils.isBlank(resourceId)) {
throw new RedfishException(String.format("Command '%s' requires a valid resource ID '%s'.", cmd, resourceId));
}
return String.format("%s%s%s", SYSTEMS_URL_PATH, resourceId, COMPUTER_SYSTEM_RESET_URL_PATH);
return String.format("%s/%s/%s", SYSTEMS_URL_PATH, resourceId, COMPUTER_SYSTEM_RESET_URL_PATH);
default:
throw new RedfishException(String.format("Redfish client does not support command '%s'.", cmd));
}
Expand Down Expand Up @@ -305,8 +309,8 @@

int statusCode = response.getStatusLine().getStatusCode();
if (statusCode < HttpStatus.SC_OK || statusCode >= HttpStatus.SC_MULTIPLE_CHOICES) {
throw new RedfishException(String.format("Failed to get System power state for host '%s' with request '%s: %s'. The expected HTTP status code is '%s' but it got '%s'.",
HttpGet.METHOD_NAME, url, hostAddress, EXPECTED_HTTP_STATUS, statusCode));
throw new RedfishException(String.format("Failed to execute System power command for host by performing '%s' request on URL '%s' and host address '%s'. The expected HTTP status code is '%s' but it got '%s'.",
HttpPost.METHOD_NAME, url, hostAddress, EXPECTED_HTTP_STATUS, statusCode));

Check warning on line 313 in utils/src/main/java/org/apache/cloudstack/utils/redfish/RedfishClient.java

View check run for this annotation

Codecov / codecov/patch

utils/src/main/java/org/apache/cloudstack/utils/redfish/RedfishClient.java#L312-L313

Added lines #L312 - L313 were not covered by tests
}
logger.debug(String.format("Sending ComputerSystem.Reset Command '%s' to host '%s' with request '%s %s'", resetCommand, hostAddress, HttpPost.METHOD_NAME, url));
}
Expand Down Expand Up @@ -340,16 +344,25 @@
try {
in = response.getEntity().getContent();
BufferedReader streamReader = new BufferedReader(new InputStreamReader(in, StandardCharsets.UTF_8));
jsonString = streamReader.readLine();
jsonString = streamReader.lines().collect(Collectors.joining());

Check warning on line 347 in utils/src/main/java/org/apache/cloudstack/utils/redfish/RedfishClient.java

View check run for this annotation

Codecov / codecov/patch

utils/src/main/java/org/apache/cloudstack/utils/redfish/RedfishClient.java#L347

Added line #L347 was not covered by tests
} catch (UnsupportedOperationException | IOException e) {
throw new RedfishException("Failed to process system Response", e);
}

// retrieving the system ID (e.g. 'System.Embedded.1') via JsonParser:
// (...) Members":[{"@odata.id":"/redfish/v1/Systems/System.Embedded.1"}] (...)
JsonArray jArray = new JsonParser().parse(jsonString).getAsJsonObject().get(MEMBERS).getAsJsonArray();
JsonObject jsonnObject = jArray.get(0).getAsJsonObject();
String jsonObjectAsString = jsonnObject.get(ODATA_ID).getAsString();
JsonArray jArray = null;
JsonElement jsonElement = new JsonParser().parse(jsonString);

Check warning on line 355 in utils/src/main/java/org/apache/cloudstack/utils/redfish/RedfishClient.java

View check run for this annotation

Codecov / codecov/patch

utils/src/main/java/org/apache/cloudstack/utils/redfish/RedfishClient.java#L354-L355

Added lines #L354 - L355 were not covered by tests
if (jsonElement.getAsJsonObject().get(MEMBERS) != null) {
jArray = jsonElement.getAsJsonObject().get(MEMBERS).getAsJsonArray();

Check warning on line 357 in utils/src/main/java/org/apache/cloudstack/utils/redfish/RedfishClient.java

View check run for this annotation

Codecov / codecov/patch

utils/src/main/java/org/apache/cloudstack/utils/redfish/RedfishClient.java#L357

Added line #L357 was not covered by tests
} else if (jsonElement.getAsJsonObject().get(LINKS) != null){
jArray = jsonElement.getAsJsonObject().get(LINKS).getAsJsonObject().get(MEMBERS).getAsJsonArray();

Check warning on line 359 in utils/src/main/java/org/apache/cloudstack/utils/redfish/RedfishClient.java

View check run for this annotation

Codecov / codecov/patch

utils/src/main/java/org/apache/cloudstack/utils/redfish/RedfishClient.java#L359

Added line #L359 was not covered by tests
}
if (jArray == null || jArray.size() < 1) {
throw new CloudRuntimeException("Members not found in the Redfish Systems JSON, unable to determine Redfish system ID");

Check warning on line 362 in utils/src/main/java/org/apache/cloudstack/utils/redfish/RedfishClient.java

View check run for this annotation

Codecov / codecov/patch

utils/src/main/java/org/apache/cloudstack/utils/redfish/RedfishClient.java#L362

Added line #L362 was not covered by tests
}
JsonObject jsonObject = jArray.get(0).getAsJsonObject();
String jsonObjectAsString = jsonObject.get(ODATA_ID).getAsString();

Check warning on line 365 in utils/src/main/java/org/apache/cloudstack/utils/redfish/RedfishClient.java

View check run for this annotation

Codecov / codecov/patch

utils/src/main/java/org/apache/cloudstack/utils/redfish/RedfishClient.java#L364-L365

Added lines #L364 - L365 were not covered by tests
String[] arrayOfStrings = StringUtils.split(jsonObjectAsString, '/');

return arrayOfStrings[arrayOfStrings.length - 1];
Expand Down Expand Up @@ -384,8 +397,7 @@
try {
in = response.getEntity().getContent();
BufferedReader streamReader = new BufferedReader(new InputStreamReader(in, StandardCharsets.UTF_8));

jsonString = streamReader.readLine();
jsonString = streamReader.lines().collect(Collectors.joining());

Check warning on line 400 in utils/src/main/java/org/apache/cloudstack/utils/redfish/RedfishClient.java

View check run for this annotation

Codecov / codecov/patch

utils/src/main/java/org/apache/cloudstack/utils/redfish/RedfishClient.java#L400

Added line #L400 was not covered by tests
String powerState = new JsonParser().parse(jsonString).getAsJsonObject().get(POWER_STATE).getAsString();
return RedfishPowerState.valueOf(powerState);
} catch (UnsupportedOperationException | IOException e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,9 @@ public class RedfishClientTest {
private static final String PASSWORD = "password";
private static final String oobAddress = "oob.host.address";
private static final String systemId = "SystemID.1";
private final static String COMPUTER_SYSTEM_RESET_URL_PATH = "/Actions/ComputerSystem.Reset";
private final static String COMPUTER_SYSTEM_RESET_URL_PATH = "Actions/ComputerSystem.Reset";
private final static Integer REDFISHT_REQUEST_RETRIES = Integer.valueOf(2);
private static final String url = "https://address.system.net/redfish/v1/Systems/";
private static final String url = "https://address.system.net/redfish/v1/Systems";
private static final HttpRequestBase httpReq = new HttpGet(url);

@Mock
Expand Down Expand Up @@ -87,31 +87,31 @@ public void validateAddressAndPrepareForUrlTestIpv6() {
public void buildRequestUrlTestHttpsGetSystemId() {
RedfishClient redfishclient = new RedfishClient(USERNAME, PASSWORD, true, false, REDFISHT_REQUEST_RETRIES);
String result = redfishclient.buildRequestUrl(oobAddress, RedfishClient.RedfishCmdType.GetSystemId, systemId);
String expected = String.format("https://%s/redfish/v1/Systems/", oobAddress);
String expected = String.format("https://%s/redfish/v1/Systems", oobAddress);
Assert.assertEquals(expected, result);
}

@Test
public void buildRequestUrlTestGetSystemId() {
RedfishClient redfishclient = new RedfishClient(USERNAME, PASSWORD, false, false, REDFISHT_REQUEST_RETRIES);
String result = redfishclient.buildRequestUrl(oobAddress, RedfishClient.RedfishCmdType.GetSystemId, systemId);
String expected = String.format("http://%s/redfish/v1/Systems/", oobAddress);
String expected = String.format("http://%s/redfish/v1/Systems", oobAddress);
Assert.assertEquals(expected, result);
}

@Test
public void buildRequestUrlTestHttpsComputerSystemReset() {
RedfishClient redfishclient = new RedfishClient(USERNAME, PASSWORD, true, false, REDFISHT_REQUEST_RETRIES);
String result = redfishclient.buildRequestUrl(oobAddress, RedfishClient.RedfishCmdType.ComputerSystemReset, systemId);
String expected = String.format("https://%s/redfish/v1/Systems/%s%s", oobAddress, systemId, COMPUTER_SYSTEM_RESET_URL_PATH);
String expected = String.format("https://%s/redfish/v1/Systems/%s/%s", oobAddress, systemId, COMPUTER_SYSTEM_RESET_URL_PATH);
Assert.assertEquals(expected, result);
}

@Test
public void buildRequestUrlTestComputerSystemReset() {
RedfishClient redfishclient = new RedfishClient(USERNAME, PASSWORD, false, false, REDFISHT_REQUEST_RETRIES);
String result = redfishclient.buildRequestUrl(oobAddress, RedfishClient.RedfishCmdType.ComputerSystemReset, systemId);
String expected = String.format("http://%s/redfish/v1/Systems/%s%s", oobAddress, systemId, COMPUTER_SYSTEM_RESET_URL_PATH);
String expected = String.format("http://%s/redfish/v1/Systems/%s/%s", oobAddress, systemId, COMPUTER_SYSTEM_RESET_URL_PATH);
Assert.assertEquals(expected, result);
}

Expand Down
Loading