Java tutorial
// 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.cloudstack.outofbandmanagement.driver.nestedcloudstack; import br.com.autonomiccs.apacheCloudStack.client.ApacheCloudStackClient; import br.com.autonomiccs.apacheCloudStack.client.ApacheCloudStackRequest; import br.com.autonomiccs.apacheCloudStack.client.beans.ApacheCloudStackUser; import br.com.autonomiccs.apacheCloudStack.exceptions.ApacheCloudStackClientRequestRuntimeException; import com.cloud.utils.component.AdapterBase; import com.cloud.utils.exception.CloudRuntimeException; import com.fasterxml.jackson.databind.ObjectMapper; import com.google.common.base.Strings; import com.google.common.collect.ImmutableMap; import org.apache.cloudstack.outofbandmanagement.OutOfBandManagement; import org.apache.cloudstack.outofbandmanagement.OutOfBandManagementDriver; import org.apache.cloudstack.outofbandmanagement.driver.OutOfBandManagementDriverChangePasswordCommand; import org.apache.cloudstack.outofbandmanagement.driver.OutOfBandManagementDriverCommand; import org.apache.cloudstack.outofbandmanagement.driver.OutOfBandManagementDriverPowerCommand; import org.apache.cloudstack.outofbandmanagement.driver.OutOfBandManagementDriverResponse; import org.apache.log4j.Logger; import java.io.IOException; import java.util.List; import java.util.Map; public final class NestedCloudStackOutOfBandManagementDriver extends AdapterBase implements OutOfBandManagementDriver { private static final Logger LOG = Logger.getLogger(NestedCloudStackOutOfBandManagementDriver.class); public OutOfBandManagementDriverResponse execute(final OutOfBandManagementDriverCommand cmd) { OutOfBandManagementDriverResponse response = new OutOfBandManagementDriverResponse(null, "Unsupported Command", false); if (cmd instanceof OutOfBandManagementDriverPowerCommand) { response = execute((OutOfBandManagementDriverPowerCommand) cmd); } else if (cmd instanceof OutOfBandManagementDriverChangePasswordCommand) { throw new CloudRuntimeException( "Change password operation is not supported by the nested-cloudstack out-of-band management driver"); } return response; } protected void ensureOptionExists(final ImmutableMap<OutOfBandManagement.Option, String> options, final OutOfBandManagement.Option option) { if (options != null && option != null && options.containsKey(option) && !Strings.isNullOrEmpty(options.get(option))) { return; } throw new CloudRuntimeException( "Invalid out-of-band management configuration detected for the nested-cloudstack driver"); } protected OutOfBandManagement.PowerState getNestedVMPowerState(final String jsonResponse) { if (Strings.isNullOrEmpty(jsonResponse)) { return OutOfBandManagement.PowerState.Unknown; } final ObjectMapper mapper = new ObjectMapper(); try { Map<String, Object> listResponse = mapper.readValue(jsonResponse, Map.class); if (listResponse != null && listResponse.containsKey("listvirtualmachinesresponse") && ((Map<String, Object>) listResponse.get("listvirtualmachinesresponse")) .containsKey("virtualmachine")) { Map<String, String> vmResponse = ((Map<String, List<Map<String, String>>>) listResponse .get("listvirtualmachinesresponse")).get("virtualmachine").get(0); if (vmResponse != null && vmResponse.containsKey("state")) { if ("Running".equals(vmResponse.get("state"))) { return OutOfBandManagement.PowerState.On; } else if ("Stopped".equals(vmResponse.get("state"))) { return OutOfBandManagement.PowerState.Off; } } } } catch (IOException e) { LOG.warn( "Exception caught while de-serializing and reading state of the nested-cloudstack VM from the response: " + jsonResponse + ", with exception:", e); } return OutOfBandManagement.PowerState.Unknown; } private OutOfBandManagementDriverResponse execute(final OutOfBandManagementDriverPowerCommand cmd) { if (cmd == null || cmd.getPowerOperation() == null) { throw new CloudRuntimeException( "Invalid out-of-band management power command provided to the nested-cloudstack driver"); } final ImmutableMap<OutOfBandManagement.Option, String> options = cmd.getOptions(); ensureOptionExists(options, OutOfBandManagement.Option.ADDRESS); ensureOptionExists(options, OutOfBandManagement.Option.PORT); ensureOptionExists(options, OutOfBandManagement.Option.USERNAME); ensureOptionExists(options, OutOfBandManagement.Option.PASSWORD); final String url = options.get(OutOfBandManagement.Option.ADDRESS); final String vmUuid = options.get(OutOfBandManagement.Option.PORT); final String apiKey = options.get(OutOfBandManagement.Option.USERNAME); final String secretKey = options.get(OutOfBandManagement.Option.PASSWORD); final ApacheCloudStackUser apacheCloudStackUser = new ApacheCloudStackUser(secretKey, apiKey); final ApacheCloudStackClient client = new ApacheCloudStackClient(url, apacheCloudStackUser); client.setValidateServerHttpsCertificate(false); client.setShouldRequestsExpire(false); client.setConnectionTimeout((int) cmd.getTimeout().getStandardSeconds()); String apiName = "listVirtualMachines"; switch (cmd.getPowerOperation()) { case ON: apiName = "startVirtualMachine"; break; case OFF: case SOFT: apiName = "stopVirtualMachine"; break; case CYCLE: case RESET: apiName = "rebootVirtualMachine"; break; } final ApacheCloudStackRequest apacheCloudStackRequest = new ApacheCloudStackRequest(apiName); apacheCloudStackRequest.addParameter("response", "json"); apacheCloudStackRequest.addParameter("forced", "true"); apacheCloudStackRequest.addParameter("id", vmUuid); final String apiResponse; try { apiResponse = client.executeRequest(apacheCloudStackRequest); } catch (final ApacheCloudStackClientRequestRuntimeException e) { LOG.error("Nested CloudStack oobm plugin failed due to API error: ", e); final OutOfBandManagementDriverResponse failedResponse = new OutOfBandManagementDriverResponse( e.getResponse(), "HTTP error code: " + e.getStatusCode(), false); if (e.getStatusCode() == 401) { failedResponse.setAuthFailure(true); } return failedResponse; } final OutOfBandManagementDriverResponse response = new OutOfBandManagementDriverResponse(apiResponse, null, true); if (OutOfBandManagement.PowerOperation.STATUS.equals(cmd.getPowerOperation())) { response.setPowerState(getNestedVMPowerState(apiResponse)); } return response; } }