/* * Copyright (c) 2016 Red Hat, Inc. and/or its affiliates. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Cheng Fang - Initial API and implementation */ package org.jberet.rest.client; import java.net.URI; import java.util.Properties; import javax.ws.rs.client.Client; import javax.ws.rs.client.ClientBuilder; import javax.ws.rs.client.Entity; import javax.ws.rs.client.WebTarget; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.UriBuilder; import org.jberet.rest.entity.JobExecutionEntity; import org.jberet.rest.entity.JobInstanceEntity; import org.jberet.rest.entity.StepExecutionEntity; import org.jberet.rest.resource.JobExecutionResource; import org.jberet.rest.resource.JobInstanceResource; import org.jberet.rest.resource.JobResource; import org.jberet.rest.resource.JobScheduleResource; import org.jberet.schedule.JobSchedule; import org.jberet.schedule.JobScheduleConfig; /** * Common batch client operations via REST API. * * @since 1.3.0 */ public class BatchClient { private final Client client; private final String restUrl; /** * Constructs {@code BatchClient} with the specified REST URL. * * @param restUrl REST URL, for example, http://localhost:8080/app1/api */ public BatchClient(final String restUrl) { this(ClientBuilder.newClient(), restUrl); } /** * Constructs {@code BatchClient} with the specified {@code javax.ws.rs.client.Client} * and REST URL. * * @param client {@code javax.ws.rs.client.Client} * @param restUrl REST URL, for example, http://localhost:8080/app1/api */ public BatchClient(final Client client, final String restUrl) { this.client = client; this.restUrl = restUrl; } /** * Gets the {@code javax.ws.rs.client.Client} associated with this {@code BatchClient}. * @return the {@code javax.ws.rs.client.Client} */ public Client getClient() { return client; } /** * Gets the REST URL for this {@code BatchClient}. * @return REST URL, for example, http://localhost:8080/app1/api */ public String getRestUrl() { return restUrl; } /** * Starts the job specified by the job XML name and job parameters. * @param jobXmlName job XML name for the job to start * @param queryParams job parameters * @return the new job execution entity * @throws Exception if errors occur */ public JobExecutionEntity startJob(final String jobXmlName, final Properties queryParams) throws Exception { final URI uri = getJobUriBuilder("start").resolveTemplate("jobXmlName", jobXmlName).build(); WebTarget target = target(uri, queryParams); return target.request().post(Entity.entity(null, MediaType.APPLICATION_JSON_TYPE), JobExecutionEntity.class); } /** * Restarts the job execution specified by the job execution id and job parameters. * * @param jobExecutionId job execution id * @param queryParams job parameters * @return the new job execution entity * @throws Exception if errors occur */ public JobExecutionEntity restartJobExecution(final long jobExecutionId, final Properties queryParams) throws Exception { final URI uri = getJobExecutionUriBuilder("restart").resolveTemplate("jobExecutionId", jobExecutionId).build(); WebTarget target = target(uri, queryParams); return target.request().post(Entity.entity(null, MediaType.APPLICATION_JSON_TYPE), JobExecutionEntity.class); } /** * Restarts the latest failed or stopped job execution belonging to the * specified job name. * This method is equivalent to first finding the latest failed or stopped * job execution belonging to the job name, and then restarting that job * execution id. * * @param jobXmlName job name (id) * @param queryParams job parameters * @return the new job execution entity * @throws Exception if errors occur */ public JobExecutionEntity restartJobExecution(final String jobXmlName, final Properties queryParams) throws Exception { final URI uri = getJobUriBuilder("restart").resolveTemplate("jobXmlName", jobXmlName).build(); WebTarget target = target(uri, queryParams); return target.request().post(Entity.entity(null, MediaType.APPLICATION_JSON_TYPE), JobExecutionEntity.class); } /** * Gets all job instances belonging to the specified job name, * in reverse chronological order. * * @param jobName the job name * @param start the relative starting number (zero based) to * return from the maximal list of job instances * @param count the number of job instances to return from the * starting position of the maximal list of job instances * @return matching job instances * @throws Exception if errors occur */ public JobInstanceEntity[] getJobInstances(final String jobName, final int start, final int count) throws Exception { final URI uri = getJobInstanceUriBuilder(null).build(); final WebTarget target = target(uri) .queryParam("jobName", jobName) .queryParam("start", start) .queryParam("count", count); return target.request().get(JobInstanceEntity[].class); } /** * Gets the {@code javax.ws.rs.client.WebTarget} for the specified URI. * * @param uri uri * @return {@code javax.ws.rs.client.WebTarget} for the uri */ public WebTarget target(final URI uri) { return client.target(uri); } /** * Gets the {@code javax.ws.rs.client.WebTarget} for the specified URI and * query parameters. * * @param uri uri * @param props query parameters * @return {@code javax.ws.rs.client.WebTarget} */ public WebTarget target(final URI uri, final Properties props) { WebTarget result = client.target(uri); if (props == null) { return result; } else { for (final String k : props.stringPropertyNames()) { result = result.queryParam(k, props.getProperty(k)); } } return result; } /** * Gets the job execution entity for the specified job execution id. * @param jobExecutionId job execution id * @return job execution entity */ public JobExecutionEntity getJobExecution(final long jobExecutionId) { final URI uri = getJobExecutionUriBuilder(null).path(String.valueOf(jobExecutionId)).build(); final WebTarget target = client.target(uri); return target.request().get(JobExecutionEntity.class); } /** * Gets all step execution entities for the specified job execution id. * @param jobExecutionId job execution id * @return all step execution entities */ public StepExecutionEntity[] getStepExecutions(final long jobExecutionId) { final URI uri = getJobExecutionUriBuilder("getStepExecutions") .resolveTemplate("jobExecutionId", jobExecutionId).build(); WebTarget target = target(uri); return target.request().get(StepExecutionEntity[].class); } /** * Gets the job schedule for the specified job schedule id. * @param scheduleId job schedule id * @return job schedule */ public JobSchedule getJobSchedule(final String scheduleId) { final URI uri = getJobScheduleUriBuilder("getJobSchedule") .resolveTemplate("scheduleId", scheduleId).build(); WebTarget target = target(uri); return target.request().accept(MediaType.APPLICATION_JSON_TYPE).get(JobSchedule.class); } /** * Gets all job schedules for the current job scheduler. * @return all job schedules */ public JobSchedule[] getJobSchedules() { final URI uri = getJobScheduleUriBuilder("getJobSchedules").build(); final WebTarget target = target(uri); return target.request().accept(MediaType.APPLICATION_JSON_TYPE).get(JobSchedule[].class); } /** * Gets all feature names supported by the current job scheduler. * @return all feature names as a string array */ public String[] getJobScheduleFeatures() { final URI uri = getJobScheduleUriBuilder("getFeatures").build(); final WebTarget target = target(uri); return target.request().accept(MediaType.APPLICATION_JSON_TYPE).get(String[].class); } /** * Cancels the job schedule specified by the job schedule id. * @param scheduleId job schedule id * @return true if successfully cancelled; false otherwise */ public boolean cancelJobSchedule(final String scheduleId) { final URI uri = getJobScheduleUriBuilder("cancel") .resolveTemplate("scheduleId", scheduleId).build(); WebTarget target = target(uri); return target.request().accept(MediaType.APPLICATION_JSON_TYPE) .post(Entity.entity(null, MediaType.APPLICATION_JSON_TYPE), boolean.class); } /** * Submits a job schedule as specified by the job schedule config. * @param scheduleConfig job schedule config * @return the new job schedule from the submission */ public JobSchedule schedule(final JobScheduleConfig scheduleConfig) { final URI uri; if (scheduleConfig.getJobName() != null) { uri = getJobUriBuilder("schedule").resolveTemplate("jobXmlName", scheduleConfig.getJobName()).build(); } else { uri = getJobExecutionUriBuilder("schedule") .resolveTemplate("jobExecutionId", scheduleConfig.getJobExecutionId()).build(); } WebTarget target = target(uri); return target.request().post(Entity.json(scheduleConfig), JobSchedule.class); } /** * Gets the {@code javax.ws.rs.core.UriBuilder} for the specified * REST resource class and method. * * @param cls REST resource class name * @param methodName name of the resource method in the above REST resource class * @return {@code javax.ws.rs.core.UriBuilder} */ public UriBuilder getUriBuilder(final Class<?> cls, final String methodName) { UriBuilder uriBuilder = UriBuilder.fromPath(restUrl).path(cls); if (methodName != null) { uriBuilder = uriBuilder.path(cls, methodName); } return uriBuilder; } /** * Gets the {@code javax.ws.rs.core.UriBuilder} for the specified method * name in {@link JobResource} class. * * @param methodName method name in {@code JobResource} class * @return {@code javax.ws.rs.core.UriBuilder} */ public UriBuilder getJobUriBuilder(final String methodName) { return getUriBuilder(JobResource.class, methodName); } /** * Gets the {@code javax.ws.rs.core.UriBuilder} for the specified method * name in {@link JobInstanceResource} class. * * @param methodName method name in {@code JobInstanceResource} class * @return {@code javax.ws.rs.core.UriBuilder} */ public UriBuilder getJobInstanceUriBuilder(final String methodName) { return getUriBuilder(JobInstanceResource.class, methodName); } /** * Gets the {@code javax.ws.rs.core.UriBuilder} for the specified method * name in {@link JobExecutionResource} class. * * @param methodName method name in {@code JobExecutionResource} class * @return {@code javax.ws.rs.core.UriBuilder} */ public UriBuilder getJobExecutionUriBuilder(final String methodName) { return getUriBuilder(JobExecutionResource.class, methodName); } /** * Gets the {@code javax.ws.rs.core.UriBuilder} for the specified method * name in {@link JobScheduleResource} class. * * @param methodName method name in {@code JobScheduleResource} class * @return {@code javax.ws.rs.core.UriBuilder} */ public UriBuilder getJobScheduleUriBuilder(final String methodName) { return getUriBuilder(JobScheduleResource.class, methodName); } }