/* * 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.services.impl.controller; import java.net.URLEncoder; import java.util.Set; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import org.kie.server.common.rest.KieServerHttpRequest; import org.kie.server.common.rest.KieServerHttpResponse; import org.kie.server.api.KieServerConstants; import org.kie.server.api.KieServerEnvironment; import org.kie.server.api.marshalling.MarshallerFactory; import org.kie.server.api.marshalling.MarshallingException; import org.kie.server.api.marshalling.MarshallingFormat; import org.kie.server.api.model.KieServerConfig; import org.kie.server.api.model.KieServerInfo; import org.kie.server.controller.api.KieServerController; import org.kie.server.controller.api.model.KieServerSetup; import org.kie.server.services.api.KieControllerNotConnectedException; import org.kie.server.services.api.KieControllerNotDefinedException; import org.kie.server.services.api.KieServerRegistry; import org.kie.server.services.impl.storage.KieServerState; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class DefaultRestControllerImpl implements KieServerController { private static final Logger logger = LoggerFactory.getLogger(DefaultRestControllerImpl.class); private final KieServerRegistry context; public DefaultRestControllerImpl(KieServerRegistry context) { this.context = context; } @SuppressWarnings("unchecked") protected <T> T makeHttpPutRequestAndCreateCustomResponse(String uri, String body, Class<T> resultType, String user, String password, String token) { logger.debug("About to send PUT request to '{}' with payload '{}'", uri, body); KieServerHttpRequest request = newRequest( uri, user, password, token ).body(body).put(); KieServerHttpResponse response = request.response(); if ( response.code() == Response.Status.CREATED.getStatusCode() || response.code() == Response.Status.BAD_REQUEST.getStatusCode() ) { T serviceResponse = deserialize( response.body(), resultType ); return serviceResponse; } else { throw new IllegalStateException( "Error while sending PUT request to " + uri + " response code " + response.code() ); } } @SuppressWarnings("unchecked") protected <T> T makeHttpPostRequestAndCreateCustomResponse(String uri, String body, Class<T> resultType, String user, String password, String token) { logger.debug("About to send POST request to '{}' with payload '{}'", uri, body); KieServerHttpRequest request = newRequest( uri, user, password, token ).body(body).post(); KieServerHttpResponse response = request.response(); if ( response.code() == Response.Status.CREATED.getStatusCode() || response.code() == Response.Status.BAD_REQUEST.getStatusCode() || response.code() == Response.Status.OK.getStatusCode()) { T serviceResponse = deserialize( response.body(), resultType ); return serviceResponse; } else { throw new IllegalStateException( "Error while sending POST request to " + uri + " response code " + response.code() ); } } @SuppressWarnings("unchecked") protected <T> T makeHttpDeleteRequestAndCreateCustomResponse(String uri, Class<T> resultType, String user, String password, String token) { logger.debug("About to send DELETE request to '{}' ", uri); KieServerHttpRequest request = newRequest( uri, user, password, token ).delete(); KieServerHttpResponse response = request.response(); if ( response.code() == Response.Status.OK.getStatusCode() || response.code() == Response.Status.NO_CONTENT.getStatusCode() ) { T serviceResponse = deserialize( response.body(), resultType); return serviceResponse; } else { throw new IllegalStateException( "Error while sending DELETE request to " + uri + " response code " + response.code() ); } } private KieServerHttpRequest newRequest(String uri, String userName, String password, String token) { KieServerHttpRequest httpRequest = KieServerHttpRequest.newRequest(uri).followRedirects(true).timeout(5000); httpRequest.accept(MediaType.APPLICATION_JSON); if (token != null && !token.isEmpty()) { httpRequest.tokenAuthorization(token); } else { httpRequest.basicAuthorization(userName, password); } return httpRequest; } private <T> T deserialize(String content, Class<T> type) { if (type == null) { return null; } try { return MarshallerFactory.getMarshaller(MarshallingFormat.JSON, this.getClass().getClassLoader()).unmarshall(content, type); } catch ( MarshallingException e ) { throw new IllegalStateException( "Error while deserializing data received from server!", e ); } } protected String serialize(Object object) { if (object == null) { return ""; } try { return MarshallerFactory.getMarshaller(MarshallingFormat.JSON, this.getClass().getClassLoader()).marshall(object); } catch ( MarshallingException e ) { throw new IllegalStateException( "Error while serializing request data!", e ); } } @Override public KieServerSetup connect(KieServerInfo serverInfo) { KieServerState currentState = context.getStateRepository().load(KieServerEnvironment.getServerId()); Set<String> controllers = currentState.getControllers(); KieServerConfig config = currentState.getConfiguration(); if (controllers != null && !controllers.isEmpty()) { for (String controllerUrl : controllers) { if (controllerUrl != null && !controllerUrl.isEmpty()) { String connectAndSyncUrl = controllerUrl + "/server/" + KieServerEnvironment.getServerId(); String userName = config.getConfigItemValue(KieServerConstants.CFG_KIE_CONTROLLER_USER, "kieserver"); String password = config.getConfigItemValue(KieServerConstants.CFG_KIE_CONTROLLER_PASSWORD, "kieserver1!"); String token = config.getConfigItemValue(KieServerConstants.CFG_KIE_CONTROLLER_TOKEN); try { KieServerSetup kieServerSetup = makeHttpPutRequestAndCreateCustomResponse(connectAndSyncUrl, serialize(serverInfo), KieServerSetup.class, userName, password, token); if (kieServerSetup != null) { // once there is non null list let's return it return kieServerSetup; } break; } catch (Exception e) { // let's check all other controllers in case of running in cluster of controllers logger.warn("Exception encountered while syncing with controller at {} error {}", connectAndSyncUrl, e.getCause() == null ? e.getMessage() : e.getCause().getMessage()); logger.debug("Exception encountered while syncing with controller at {} error {}", connectAndSyncUrl, e.getMessage(), e); } } } throw new KieControllerNotConnectedException("Unable to connect to any controller"); } else { throw new KieControllerNotDefinedException("Unable to connect to any controller"); } } @Override public void disconnect(KieServerInfo serverInfo) { KieServerState currentState = context.getStateRepository().load(KieServerEnvironment.getServerId()); Set<String> controllers = currentState.getControllers(); KieServerConfig config = currentState.getConfiguration(); for (String controllerUrl : controllers ) { if (controllerUrl != null && !controllerUrl.isEmpty()) { String connectAndSyncUrl = null; try { connectAndSyncUrl = controllerUrl + "/server/" + KieServerEnvironment.getServerId()+"/?location="+ URLEncoder.encode(serverInfo.getLocation(), "UTF-8"); String userName = config.getConfigItemValue(KieServerConstants.CFG_KIE_CONTROLLER_USER, "kieserver"); String password = config.getConfigItemValue(KieServerConstants.CFG_KIE_CONTROLLER_PASSWORD, "kieserver1!"); String token = config.getConfigItemValue(KieServerConstants.CFG_KIE_CONTROLLER_TOKEN); makeHttpDeleteRequestAndCreateCustomResponse(connectAndSyncUrl, null, userName, password, token); break; } catch (Exception e) { // let's check all other controllers in case of running in cluster of controllers logger.debug("Exception encountered while syncing with controller at {} error {}", connectAndSyncUrl, e.getMessage(), e); } } } } public void startContainer(String containerId) { KieServerState currentState = context.getStateRepository().load(KieServerEnvironment.getServerId()); Set<String> controllers = currentState.getControllers(); KieServerConfig config = currentState.getConfiguration(); if (controllers != null && !controllers.isEmpty()) { for (String controllerUrl : controllers) { if (controllerUrl != null && !controllerUrl.isEmpty()) { String connectAndSyncUrl = controllerUrl + "/management/servers/" + KieServerEnvironment.getServerId() + "/containers/" + containerId + "/status/started"; String userName = config.getConfigItemValue(KieServerConstants.CFG_KIE_CONTROLLER_USER, "kieserver"); String password = config.getConfigItemValue(KieServerConstants.CFG_KIE_CONTROLLER_PASSWORD, "kieserver1!"); String token = config.getConfigItemValue(KieServerConstants.CFG_KIE_CONTROLLER_TOKEN); try { makeHttpPostRequestAndCreateCustomResponse(connectAndSyncUrl, "", null, userName, password, token); break; } catch (Exception e) { // let's check all other controllers in case of running in cluster of controllers logger.warn("Exception encountered while syncing with controller at {} error {}", connectAndSyncUrl, e.getCause() == null ? e.getMessage() : e.getCause().getMessage()); logger.debug("Exception encountered while syncing with controller at {} error {}", connectAndSyncUrl, e.getMessage(), e); } } } } } public void stopContainer(String containerId) { KieServerState currentState = context.getStateRepository().load(KieServerEnvironment.getServerId()); Set<String> controllers = currentState.getControllers(); KieServerConfig config = currentState.getConfiguration(); if (controllers != null && !controllers.isEmpty()) { for (String controllerUrl : controllers) { if (controllerUrl != null && !controllerUrl.isEmpty()) { String connectAndSyncUrl = controllerUrl + "/management/servers/" + KieServerEnvironment.getServerId() + "/containers/" + containerId + "/status/stopped"; String userName = config.getConfigItemValue(KieServerConstants.CFG_KIE_CONTROLLER_USER, "kieserver"); String password = config.getConfigItemValue(KieServerConstants.CFG_KIE_CONTROLLER_PASSWORD, "kieserver1!"); String token = config.getConfigItemValue(KieServerConstants.CFG_KIE_CONTROLLER_TOKEN); try { makeHttpPostRequestAndCreateCustomResponse(connectAndSyncUrl, "", null, userName, password, token); break; } catch (Exception e) { // let's check all other controllers in case of running in cluster of controllers logger.warn("Exception encountered while syncing with controller at {} error {}", connectAndSyncUrl, e.getCause() == null ? e.getMessage() : e.getCause().getMessage()); logger.debug("Exception encountered while syncing with controller at {} error {}", connectAndSyncUrl, e.getMessage(), e); } } } } } }