/* * Copyright 2016 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.controller.impl; import java.util.ArrayList; import java.util.List; import org.kie.server.api.KieServerConstants; import org.kie.server.api.marshalling.MarshallingFormat; import org.kie.server.api.model.KieContainerResource; import org.kie.server.api.model.KieContainerResourceList; import org.kie.server.api.model.KieContainerStatus; import org.kie.server.api.model.KieScannerResource; import org.kie.server.api.model.KieScannerStatus; import org.kie.server.api.model.KieServerConfigItem; import org.kie.server.api.model.Message; import org.kie.server.api.model.ReleaseId; import org.kie.server.api.model.ServiceResponse; import org.kie.server.client.KieServicesClient; import org.kie.server.client.KieServicesConfiguration; import org.kie.server.client.KieServicesFactory; import org.kie.server.client.credentials.EnteredTokenCredentialsProvider; import org.kie.server.controller.api.model.runtime.Container; import org.kie.server.controller.api.model.runtime.ServerInstanceKey; import org.kie.server.controller.api.model.spec.Capability; import org.kie.server.controller.api.model.spec.ContainerConfig; import org.kie.server.controller.api.model.spec.ContainerSpec; import org.kie.server.controller.api.model.spec.ProcessConfig; import org.kie.server.controller.api.model.spec.RuleConfig; import org.kie.server.controller.api.model.spec.ServerTemplate; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class KieServerInstanceManager { private static final Logger logger = LoggerFactory.getLogger(KieServerInstanceManager.class); private static final String CONTAINERS_URI_PART = "/containers/"; private static KieServerInstanceManager INSTANCE = new KieServerInstanceManager(); public static KieServerInstanceManager getInstance() { return INSTANCE; } public List<Container> startScanner(ServerTemplate serverTemplate, final ContainerSpec containerSpec, final long interval) { return callRemoteKieServerOperation(serverTemplate, containerSpec, new RemoteKieServerOperation<Void>(){ @Override public Void doOperation(KieServicesClient client, Container container) { KieScannerResource scannerResource = new KieScannerResource(); scannerResource.setPollInterval(interval); scannerResource.setStatus(KieScannerStatus.STARTED); ServiceResponse<KieScannerResource> response = client.updateScanner(containerSpec.getId(), scannerResource); if (!response.getType().equals(ServiceResponse.ResponseType.SUCCESS)) { logger.debug("Scanner failed to start on server instance {} due to {}", container.getUrl(), response.getMsg()); } collectContainerInfo(containerSpec, client, container); return null; } }); } public List<Container> stopScanner(ServerTemplate serverTemplate, final ContainerSpec containerSpec) { return callRemoteKieServerOperation(serverTemplate, containerSpec, new RemoteKieServerOperation<Void>(){ @Override public Void doOperation(KieServicesClient client, Container container) { KieScannerResource scannerResource = new KieScannerResource(); scannerResource.setPollInterval(null); scannerResource.setStatus(KieScannerStatus.STOPPED); ServiceResponse<KieScannerResource> response = client.updateScanner(containerSpec.getId(), scannerResource); if (!response.getType().equals(ServiceResponse.ResponseType.SUCCESS)) { logger.debug("Scanner failed to stop on server instance {} due to {}", container.getUrl(), response.getMsg()); } collectContainerInfo(containerSpec, client, container); return null; } }); } public List<Container> scanNow(ServerTemplate serverTemplate, final ContainerSpec containerSpec) { return callRemoteKieServerOperation(serverTemplate, containerSpec, new RemoteKieServerOperation<Void>(){ @Override public Void doOperation(KieServicesClient client, Container container) { KieScannerResource scannerResource = new KieScannerResource(); scannerResource.setPollInterval(null); scannerResource.setStatus(KieScannerStatus.SCANNING); ServiceResponse<KieScannerResource> response = client.updateScanner(containerSpec.getId(), scannerResource); if (!response.getType().equals(ServiceResponse.ResponseType.SUCCESS)) { logger.debug("Scanner (scan now) failed on server instance {} due to {}", container.getUrl(), response.getMsg()); } collectContainerInfo(containerSpec, client, container); return null; } }); } public List<Container> startContainer(ServerTemplate serverTemplate, final ContainerSpec containerSpec) { return callRemoteKieServerOperation(serverTemplate, containerSpec, new RemoteKieServerOperation<Void>(){ @Override public Void doOperation(KieServicesClient client, Container container) { KieContainerResource containerResource = new KieContainerResource(containerSpec.getId(), containerSpec.getReleasedId(), container.getResolvedReleasedId(), container.getStatus()); containerResource.setContainerAlias(containerSpec.getContainerName()); containerResource.setMessages((List<Message>) container.getMessages()); if (containerSpec.getConfigs() != null) { // cover scanner and rules config ContainerConfig containerConfig = containerSpec.getConfigs().get(Capability.RULE); if (containerConfig != null) { RuleConfig ruleConfig = (RuleConfig) containerConfig; KieScannerResource scannerResource = new KieScannerResource(); scannerResource.setPollInterval(ruleConfig.getPollInterval()); scannerResource.setStatus(ruleConfig.getScannerStatus()); containerResource.setScanner(scannerResource); } // cover process config containerConfig = containerSpec.getConfigs().get(Capability.PROCESS); if (containerConfig != null) { ProcessConfig processConfig = (ProcessConfig) containerConfig; KieServerConfigItem configItem = new KieServerConfigItem(); configItem.setType(KieServerConstants.CAPABILITY_BPM); configItem.setName(KieServerConstants.PCFG_KIE_BASE); configItem.setValue(processConfig.getKBase()); containerResource.addConfigItem(configItem); configItem = new KieServerConfigItem(); configItem.setType(KieServerConstants.CAPABILITY_BPM); configItem.setName(KieServerConstants.PCFG_KIE_SESSION); configItem.setValue(processConfig.getKSession()); containerResource.addConfigItem(configItem); configItem = new KieServerConfigItem(); configItem.setType(KieServerConstants.CAPABILITY_BPM); configItem.setName(KieServerConstants.PCFG_MERGE_MODE); configItem.setValue(processConfig.getMergeMode()); containerResource.addConfigItem(configItem); configItem = new KieServerConfigItem(); configItem.setType(KieServerConstants.CAPABILITY_BPM); configItem.setName(KieServerConstants.PCFG_RUNTIME_STRATEGY); configItem.setValue(processConfig.getRuntimeStrategy()); containerResource.addConfigItem(configItem); } } ServiceResponse<KieContainerResource> response = client.createContainer(containerSpec.getId(), containerResource); if (!response.getType().equals(ServiceResponse.ResponseType.SUCCESS)) { logger.debug("Container {} failed to start on server instance {} due to {}", containerSpec.getId(), container.getUrl(), response.getMsg()); } collectContainerInfo(containerSpec, client, container); return null; } }); } public List<Container> stopContainer(ServerTemplate serverTemplate, final ContainerSpec containerSpec) { return callRemoteKieServerOperation(serverTemplate, containerSpec, new RemoteKieServerOperation<Void>(){ @Override public Void doOperation(KieServicesClient client, Container container) { ServiceResponse<Void> response = client.disposeContainer(containerSpec.getId()); if (!response.getType().equals(ServiceResponse.ResponseType.SUCCESS)) { logger.debug("Container {} failed to stop on server instance {} due to {}", containerSpec.getId(), container.getUrl(), response.getMsg()); } collectContainerInfo(containerSpec, client, container); return null; } }); } public List<Container> upgradeContainer(ServerTemplate serverTemplate, final ContainerSpec containerSpec) { return callRemoteKieServerOperation(serverTemplate, containerSpec, new RemoteKieServerOperation<Void>(){ @Override public Void doOperation(KieServicesClient client, Container container) { ServiceResponse<ReleaseId> response = client.updateReleaseId(containerSpec.getId(), containerSpec.getReleasedId()); if (!response.getType().equals(ServiceResponse.ResponseType.SUCCESS)) { logger.debug("Container {} failed to upgrade on server instance {} due to {}", containerSpec.getId(), container.getUrl(), response.getMsg()); } collectContainerInfo(containerSpec, client, container); return null; } }); } public List<Container> getContainers(final ServerTemplate serverTemplate, final ContainerSpec containerSpec) { return callRemoteKieServerOperation(serverTemplate, containerSpec, new RemoteKieServerOperation<Void>(){ @Override public Void doOperation(KieServicesClient client, Container container) { if (containerSpec.getStatus().equals(KieContainerStatus.STARTED)) { ServiceResponse<KieContainerResource> response = client.getContainerInfo(containerSpec.getId()); if (response.getType().equals(ServiceResponse.ResponseType.SUCCESS)) { KieContainerResource containerResource = response.getResult(); container.setContainerSpecId(containerResource.getContainerId()); container.setContainerName(containerResource.getContainerId()); container.setResolvedReleasedId(containerResource.getResolvedReleaseId() == null ? containerResource.getReleaseId() : containerResource.getResolvedReleaseId()); container.setServerTemplateId(serverTemplate.getId()); container.setStatus(containerResource.getStatus()); container.setMessages(containerResource.getMessages()); } } return null; } }); } public List<Container> getContainers(ServerInstanceKey serverInstanceKey) { List<Container> containers = new ArrayList<org.kie.server.controller.api.model.runtime.Container>(); if (serverInstanceKey == null || serverInstanceKey.getUrl() == null) { return containers; } try { KieServicesClient client = getClient(serverInstanceKey.getUrl()); ServiceResponse<KieContainerResourceList> response = client.listContainers(); if (response.getType().equals(ServiceResponse.ResponseType.SUCCESS)) { KieContainerResourceList resourceList = response.getResult(); for (KieContainerResource containerResource : resourceList.getContainers()) { Container container = new Container(); container.setContainerSpecId(containerResource.getContainerId()); container.setContainerName(containerResource.getContainerId()); container.setServerInstanceId(serverInstanceKey.getServerInstanceId()); container.setUrl(serverInstanceKey.getUrl() + CONTAINERS_URI_PART + containerResource.getContainerId()); container.setResolvedReleasedId(containerResource.getResolvedReleaseId() == null ? containerResource.getReleaseId():containerResource.getResolvedReleaseId()); container.setServerTemplateId(serverInstanceKey.getServerTemplateId()); container.setStatus(containerResource.getStatus()); container.setMessages(containerResource.getMessages()); containers.add(container); } } } catch (Exception e) { logger.warn("Unable to get list of containers from remote server at url {} due to {}", serverInstanceKey.getUrl(), e.getMessage()); } return containers; } /* * helper methods */ protected List<Container> callRemoteKieServerOperation(ServerTemplate serverTemplate, ContainerSpec containerSpec, RemoteKieServerOperation operation) { List<Container> containers = new ArrayList<org.kie.server.controller.api.model.runtime.Container>(); if (serverTemplate.getServerInstanceKeys() == null || serverTemplate.getServerInstanceKeys().isEmpty()) { return containers; } for (ServerInstanceKey instanceUrl : serverTemplate.getServerInstanceKeys()) { Container container = new Container(); container.setContainerSpecId(containerSpec.getId()); container.setServerTemplateId(serverTemplate.getId()); container.setServerInstanceId(instanceUrl.getServerInstanceId()); container.setUrl(instanceUrl.getUrl() + "/containers/" + containerSpec.getId()); container.setResolvedReleasedId(containerSpec.getReleasedId()); container.setStatus(containerSpec.getStatus()); try { KieServicesClient client = getClient(instanceUrl.getUrl()); operation.doOperation(client, container); } catch (Exception e) { logger.debug("Unable to connect to {}", instanceUrl); } containers.add(container); } return containers; } public boolean isAlive(ServerInstanceKey serverInstanceKey) { boolean alive = false; try { // get client will internally call serverinfo getClient(serverInstanceKey.getUrl()); alive = true; } catch (Exception e) { logger.debug("Unable to connect to server instance at {} due to {}", serverInstanceKey.getUrl(), e.getMessage()); } return alive; } protected KieServicesClient getClient(String url) { KieServicesConfiguration configuration = KieServicesFactory.newRestConfiguration(url, getUser(), getPassword()); configuration.setTimeout(60000); configuration.setMarshallingFormat(MarshallingFormat.JSON); String authToken = getToken(); if (authToken != null && !authToken.isEmpty()) { configuration.setCredentialsProvider(new EnteredTokenCredentialsProvider(authToken)); } KieServicesClient kieServicesClient = KieServicesFactory.newKieServicesClient(configuration); return kieServicesClient; } protected void collectContainerInfo(ContainerSpec containerSpec, KieServicesClient client, Container container) { // collect up to date information ServiceResponse<KieContainerResource> serviceResponse = client.getContainerInfo(containerSpec.getId()); if (serviceResponse.getType().equals(ServiceResponse.ResponseType.SUCCESS)) { KieContainerResource containerResource = serviceResponse.getResult(); container.setMessages(containerResource.getMessages()); } } protected String getUser() { return System.getProperty(KieServerConstants.CFG_KIE_USER, "kieserver"); } protected String getPassword() { return System.getProperty(KieServerConstants.CFG_KIE_PASSWORD, "kieserver1!"); } protected String getToken() { return System.getProperty(KieServerConstants.CFG_KIE_TOKEN); } protected class RemoteKieServerOperation<T> { public T doOperation(KieServicesClient client, Container container) { return null; } } }