package org.overlord.dtgov.services.rhq; import static com.jayway.restassured.RestAssured.basic; import static com.jayway.restassured.RestAssured.given; import static org.hamcrest.Matchers.endsWith; import static org.hamcrest.Matchers.isOneOf; import static org.hamcrest.Matchers.startsWith; import java.io.IOException; import java.util.List; import java.util.Map; import org.codehaus.jackson.map.ObjectMapper; import org.overlord.dtgov.common.exception.ConfigException; import org.overlord.dtgov.services.i18n.Messages; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.jayway.restassured.RestAssured; import com.jayway.restassured.http.ContentType; import com.jayway.restassured.path.json.JsonPath; import com.jayway.restassured.response.Header; import com.jayway.restassured.response.Response; public class RHQDeployUtil { private final Logger logger = LoggerFactory.getLogger(this.getClass()); static final String APPLICATION_JSON = "application/json"; //$NON-NLS-1$ static Header acceptJson = new Header("Accept", APPLICATION_JSON); //$NON-NLS-1$ String rhqUser, rhqPassword, rhqPluginName; public RHQDeployUtil(String rhqUser, String rhqPassword, String rhqBaseUrl, Integer rhqPort, String rhqPluginname) { super(); RestAssured.baseURI = rhqBaseUrl; RestAssured.port = rhqPort; RestAssured.basePath = "/rest/"; //$NON-NLS-1$ this.rhqUser = rhqUser; this.rhqPluginName = rhqPluginname; this.rhqPassword = rhqPassword; RestAssured.authentication = basic(rhqUser,rhqPassword); } /** * Looks up the group id in RHQ for the given group name. * * @param groupName - name of the group * @return - the group id in RHQ * @throws ConfigException */ public Integer getGroupIdForGroup(String groupName) throws ConfigException { Response response = given() .header(acceptJson) .queryParam("q", groupName) //$NON-NLS-1$ .expect() .statusCode(200) .when() .get("/group"); //$NON-NLS-1$ JsonPath jsonPath = response.jsonPath(); if (! jsonPath.prettify().contains("\"id\"")) { //$NON-NLS-1$ throw new ConfigException(Messages.i18n.format("RHQDeployUtil.MissingGroup", groupName, jsonPath.prettify())); //$NON-NLS-1$ } int groupId = jsonPath.getInt("[0].id"); //$NON-NLS-1$ return groupId; } /** * Given a RHQ Group this will return a the resource Ids in this * Group. * * @param groupId - the group's RHQ id. * @return a list of resourceIds in this group. */ public List<Integer> getServerIdsForGroup(Integer groupId) { Response response = given() .header(acceptJson) .pathParam("groupId", groupId) //$NON-NLS-1$ .expect() .statusCode(200) .when() .get("/group/{groupId}/resources"); //$NON-NLS-1$ JsonPath jsonPath = response.jsonPath(); List<Integer> resourceIds = jsonPath.get("resourceId"); //$NON-NLS-1$ return resourceIds; } /** * In RHQ the group needs be a grouping of JBossAS7/EAP6 SERVERs * @param as7Id * @param in * @param artifactName * @throws IOException */ public void deploy(Integer as7Id, byte[] bytes, String artifactName) throws IOException { String handle = null; try { //int size = bytes.length; handle = given() .auth().preemptive().basic(rhqUser, rhqPassword) .body(bytes) .contentType(ContentType.BINARY) .header(acceptJson) .expect() .statusCode(isOneOf(200, 201)) .body("value", startsWith("rhq-rest-")) //$NON-NLS-1$ //$NON-NLS-2$ .body("value",endsWith(".bin")) //$NON-NLS-1$ //$NON-NLS-2$ .when() .post("/content/fresh") //$NON-NLS-1$ .jsonPath() .getString("value"); //$NON-NLS-1$ CreateCBRRequest resource = new CreateCBRRequest(); resource.setParentId(as7Id); resource.setResourceName(artifactName); // type of the new resource resource.setTypeName("Deployment"); //$NON-NLS-1$ resource.setPluginName(rhqPluginName); // set plugin config (path) and deploy config (runtime-name) resource.getPluginConfig().put("path","deployment"); //$NON-NLS-1$ //$NON-NLS-2$ resource.getResourceConfig().put("runtimeName", artifactName); //$NON-NLS-1$ ObjectMapper mapper = new ObjectMapper(); String jsonObject = mapper.writeValueAsString(resource); Response response = given().body(jsonObject) // Type of new resource .queryParam("handle", handle) //$NON-NLS-1$ .contentType(ContentType.JSON).header(acceptJson) //.log().everything() .expect() .statusCode(isOneOf(200, 201, 302)) .log().everything() .when() .post("/resource"); //$NON-NLS-1$ //System.out.println("after post"); //System.out.flush(); int status = response.getStatusCode(); String location = response.getHeader("Location"); //$NON-NLS-1$ //System.out.println("\nLocation " + location + "\n\n"); assert location!=null; // We need to check what we got. A 302 means the deploy is still // in progress, so we need to wait a little longer while (status==302) { response = given() .header(acceptJson) //.log().everything() .expect() .statusCode(isOneOf(200, 201, 302)) //.log().everything() .when() .get(location); status = response.getStatusCode(); } int createdResourceId = response.jsonPath().getInt("resourceId"); //$NON-NLS-1$ //System.out.println("\n Deploy is done, resource Id = " + createdResourceId + " \n"); //System.out.flush(); assert createdResourceId != -1; } finally { // Remove the uploaded content removeContent(handle, false); //System.out.println("\n Content removed \n"); } } private void removeContent(String handle, boolean validate) { given() .pathParam("handle", handle) //$NON-NLS-1$ .header(acceptJson) .expect() .statusCode(204) .log().ifError() .when() .delete("/content/{handle}"); //$NON-NLS-1$ } /** * Deletes (undeploys) all archives from the all AS7/EAP servers in the given * RHQ group. * @param artifactName - the name of the archive to be deleted * @param groupId - the id of the RHQ group */ @SuppressWarnings("unchecked") public void wipeArchiveIfNecessary(String artifactName, Integer groupId) { List<Resource> resources; Response response = given().queryParam("q", artifactName) //$NON-NLS-1$ .queryParam("category", "SERVICE") //$NON-NLS-1$ //$NON-NLS-2$ .queryParam("group", groupId) //$NON-NLS-1$ .header(acceptJson).expect() // .log().everything() .when().get("/resource"); //$NON-NLS-1$ if (response != null) { resources = response.as(List.class); logger.info(Messages.i18n.format("RHQDeployUtil.ManagementSummary", resources.size(), //$NON-NLS-1$ groupId, artifactName)); for (int i = 0; i < resources.size(); i++) { try { int resourceId = (Integer) ((Map<String, Object>) resources.get(i)).get("resourceId"); //$NON-NLS-1$ logger.info(Messages.i18n.format("RHQDeployUtil.DeletingDeployment", artifactName, resourceId)); //$NON-NLS-1$ given().pathParam("id", resourceId) //$NON-NLS-1$ .queryParam("physical", "true") // Also remove target on the EAP instance //$NON-NLS-1$ //$NON-NLS-2$ .expect().statusCode(204).when().delete("/resource/{id}"); //$NON-NLS-1$ } catch (Throwable t) { logger.error(Messages.i18n.format("RHQDeployUtil.DeleteFailed")); //$NON-NLS-1$ logger.error(t.getMessage()); // TODO do we need to send out somekind of notification // about this? } } } } }