/*
* Copyright 2015 Red Hat, Inc. and/or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*
* 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.kie.server.remote.rest.optaplanner;
import java.text.MessageFormat;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Variant;
import org.kie.server.api.model.ServiceResponse;
import org.kie.server.api.model.instance.SolverInstance;
import org.kie.server.api.model.instance.SolverInstanceList;
import org.kie.server.api.rest.RestURI;
import org.kie.server.remote.rest.common.Header;
import org.kie.server.remote.rest.optaplanner.resources.Messages;
import org.kie.server.services.impl.marshal.MarshallerHelper;
import org.kie.server.services.optaplanner.SolverServiceBase;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import static org.kie.server.api.rest.RestURI.CONTAINER_ID;
import static org.kie.server.api.rest.RestURI.SOLVER_BEST_SOLUTION;
import static org.kie.server.api.rest.RestURI.SOLVER_ID;
import static org.kie.server.api.rest.RestURI.SOLVER_ID_URI;
import static org.kie.server.api.rest.RestURI.SOLVER_STATE_RUNNING;
import static org.kie.server.api.rest.RestURI.SOLVER_STATE_TERMINATING;
import static org.kie.server.remote.rest.common.util.RestUtils.buildConversationIdHeader;
import static org.kie.server.remote.rest.common.util.RestUtils.createCorrectVariant;
import static org.kie.server.remote.rest.common.util.RestUtils.createResponse;
import static org.kie.server.remote.rest.common.util.RestUtils.getContentType;
import static org.kie.server.remote.rest.common.util.RestUtils.getVariant;
import static org.kie.server.remote.rest.common.util.RestUtils.internalServerError;
@Path("server/" + RestURI.SOLVER_URI)
public class SolverResource {
public static final Logger logger = LoggerFactory.getLogger(SolverResource.class);
private SolverServiceBase solverService;
private MarshallerHelper marshallerHelper;
public SolverResource() {
}
public SolverResource(SolverServiceBase solverServiceBase) {
this.solverService = solverServiceBase;
this.marshallerHelper = new MarshallerHelper(solverService.getKieServerRegistry());
}
@PUT
@Path(RestURI.SOLVER_ID_URI)
@Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
public Response createSolver(
@javax.ws.rs.core.Context HttpHeaders headers,
@PathParam(CONTAINER_ID) String containerId,
@PathParam(SOLVER_ID) String solverId,
String payload) {
logger.debug("About to create solver {} on container {}",
solverId,
containerId);
Variant v = getVariant(headers);
Header conversationIdHeader = buildConversationIdHeader(containerId,
solverService.getKieServerRegistry(),
headers);
try {
String contentType = getContentType(headers);
if (solverService.getKieServerRegistry().getContainer(containerId) == null) {
ServiceResponse<SolverInstance> response = new ServiceResponse<SolverInstance>(ServiceResponse.ResponseType.FAILURE,
"Failed to create solver. Container does not exist: " + containerId);
return createCorrectVariant(response,
headers,
Response.Status.BAD_REQUEST);
}
SolverInstance solverInstance = marshallerHelper.unmarshal(containerId,
payload,
contentType,
SolverInstance.class);
ServiceResponse<SolverInstance> response = solverService.createSolver(containerId,
solverId,
solverInstance);
if (response.getType() == ServiceResponse.ResponseType.SUCCESS) {
return createCorrectVariant(marshallerHelper,
containerId,
response.getResult(),
headers,
Response.Status.CREATED,
conversationIdHeader);
}
return createCorrectVariant(marshallerHelper,
containerId,
response.getMsg(),
headers,
Response.Status.BAD_REQUEST,
conversationIdHeader);
} catch (Exception e) {
logger.error("Unexpected error creating solver '{}' on container '{}': {}",
solverId,
containerId,
e.getMessage(),
e);
return internalServerError(MessageFormat.format(Messages.UNEXPECTED_ERROR,
e.getMessage()),
v,
conversationIdHeader);
}
}
@GET
@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
public Response getSolvers(@javax.ws.rs.core.Context HttpHeaders headers,
@PathParam(CONTAINER_ID) String containerId) {
Variant v = getVariant(headers);
Header conversationIdHeader = buildConversationIdHeader(containerId,
solverService.getKieServerRegistry(),
headers);
try {
ServiceResponse<SolverInstanceList> result = solverService.getSolvers(containerId);
if (result.getType() == ServiceResponse.ResponseType.SUCCESS) {
return createCorrectVariant(marshallerHelper,
containerId,
result.getResult(),
headers,
Response.Status.OK,
conversationIdHeader);
}
return createCorrectVariant(marshallerHelper,
containerId,
result.getMsg(),
headers,
Response.Status.NOT_FOUND,
conversationIdHeader);
} catch (Exception e) {
logger.error("Unexpected error retrieving solvers. Message: '{}'",
e.getMessage(),
e);
return internalServerError(MessageFormat.format(Messages.UNEXPECTED_ERROR,
e.getMessage()),
v,
conversationIdHeader);
}
}
@GET
@Path(RestURI.SOLVER_ID_URI)
@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
public Response getSolver(@javax.ws.rs.core.Context HttpHeaders headers,
@PathParam(CONTAINER_ID) String containerId,
@PathParam(SOLVER_ID) String solverId) {
Variant v = getVariant(headers);
Header conversationIdHeader = buildConversationIdHeader(containerId,
solverService.getKieServerRegistry(),
headers);
try {
ServiceResponse<SolverInstance> result = solverService.getSolver(containerId,
solverId);
if (result.getType() == ServiceResponse.ResponseType.SUCCESS) {
return createCorrectVariant(marshallerHelper,
containerId,
result.getResult(),
headers,
Response.Status.OK,
conversationIdHeader);
}
return createCorrectVariant(marshallerHelper,
containerId,
result.getMsg(),
headers,
Response.Status.NOT_FOUND,
conversationIdHeader);
} catch (Exception e) {
logger.error("Unexpected error retrieving solver state {}",
e.getMessage(),
e);
return internalServerError(MessageFormat.format(Messages.UNEXPECTED_ERROR,
e.getMessage()),
v,
conversationIdHeader);
}
}
@GET
@Path(SOLVER_ID_URI + "/" + SOLVER_BEST_SOLUTION)
@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
public Response getSolverWithBestSolution(@javax.ws.rs.core.Context HttpHeaders headers,
@PathParam(CONTAINER_ID) String containerId,
@PathParam(SOLVER_ID) String solverId) {
Variant v = getVariant(headers);
Header conversationIdHeader = buildConversationIdHeader(containerId,
solverService.getKieServerRegistry(),
headers);
try {
ServiceResponse<SolverInstance> result = solverService.getSolverWithBestSolution(containerId,
solverId);
if (result.getType() == ServiceResponse.ResponseType.SUCCESS) {
return createCorrectVariant(marshallerHelper,
containerId,
result.getResult(),
headers,
Response.Status.OK,
conversationIdHeader);
}
return createCorrectVariant(marshallerHelper,
containerId,
result.getMsg(),
headers,
Response.Status.NOT_FOUND,
conversationIdHeader);
} catch (Exception e) {
logger.error("Unexpected error during processing {}",
e.getMessage(),
e);
return internalServerError(MessageFormat.format(Messages.UNEXPECTED_ERROR,
e.getMessage()),
v,
conversationIdHeader);
}
}
@POST
@Path(RestURI.SOLVER_ID_URI + "/" + SOLVER_STATE_RUNNING)
@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
public Response solvePlanningProblem(@javax.ws.rs.core.Context HttpHeaders headers,
@PathParam(CONTAINER_ID) String containerId,
@PathParam(SOLVER_ID) String solverId,
String payload) {
Variant v = getVariant(headers);
Header conversationIdHeader = buildConversationIdHeader(containerId,
solverService.getKieServerRegistry(),
headers);
try {
String contentType = getContentType(headers);
Object planningProblem = marshallerHelper.unmarshal(containerId,
payload,
contentType,
Object.class);
ServiceResponse<Void> result = solverService.solvePlanningProblem(containerId,
solverId,
planningProblem);
if (result.getType() == ServiceResponse.ResponseType.SUCCESS) {
return createResponse("",
v,
Response.Status.OK,
conversationIdHeader);
}
return createCorrectVariant(marshallerHelper,
containerId,
result.getMsg(),
headers,
Response.Status.BAD_REQUEST,
conversationIdHeader);
} catch (Exception e) {
logger.error("Unexpected error retrieving solver state {}",
e.getMessage(),
e);
return internalServerError(MessageFormat.format(Messages.UNEXPECTED_ERROR,
e.getMessage()),
v,
conversationIdHeader);
}
}
@POST
@Path(RestURI.SOLVER_ID_URI + "/" + SOLVER_STATE_TERMINATING)
@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
public Response terminateSolverEarly(@javax.ws.rs.core.Context HttpHeaders headers,
@PathParam(CONTAINER_ID) String containerId,
@PathParam(SOLVER_ID) String solverId) {
Variant v = getVariant(headers);
Header conversationIdHeader = buildConversationIdHeader(containerId,
solverService.getKieServerRegistry(),
headers);
try {
ServiceResponse<Void> result = solverService.terminateSolverEarly(containerId,
solverId);
if (result.getType() == ServiceResponse.ResponseType.SUCCESS) {
return createResponse("",
v,
Response.Status.OK,
conversationIdHeader);
}
return createCorrectVariant(marshallerHelper,
containerId,
result.getMsg(),
headers,
Response.Status.BAD_REQUEST,
conversationIdHeader);
} catch (Exception e) {
logger.error("Unexpected error retrieving solver state {}",
e.getMessage(),
e);
return internalServerError(MessageFormat.format(Messages.UNEXPECTED_ERROR,
e.getMessage()),
v,
conversationIdHeader);
}
}
@DELETE
@Path(RestURI.SOLVER_ID_URI)
@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
public Response disposeSolver(@javax.ws.rs.core.Context HttpHeaders headers,
@PathParam(CONTAINER_ID) String containerId,
@PathParam(SOLVER_ID) String solverId) {
Variant v = getVariant(headers);
Header conversationIdHeader = buildConversationIdHeader(containerId,
solverService.getKieServerRegistry(),
headers);
try {
ServiceResponse<Void> result = solverService.disposeSolver(containerId,
solverId);
if (result.getType() == ServiceResponse.ResponseType.SUCCESS) {
return createResponse("",
v,
Response.Status.OK,
conversationIdHeader);
}
return createCorrectVariant(marshallerHelper,
containerId,
result.getMsg(),
headers,
Response.Status.BAD_REQUEST,
conversationIdHeader);
} catch (Exception e) {
logger.error("Unexpected error disposing solver {} on container {}. Message: '{}'",
solverId,
containerId,
e.getMessage(),
e);
return internalServerError(MessageFormat.format(Messages.UNEXPECTED_ERROR,
e.getMessage()),
v,
conversationIdHeader);
}
}
}