/* * 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.service; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; import org.kie.server.api.model.KieContainerStatus; import org.kie.server.api.model.ReleaseId; import org.kie.server.controller.api.KieServerControllerException; import org.kie.server.controller.api.KieServerControllerNotFoundException; import org.kie.server.controller.api.model.events.ServerTemplateDeleted; import org.kie.server.controller.api.model.events.ServerTemplateUpdated; import org.kie.server.controller.api.model.runtime.Container; 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.ContainerSpecKey; 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.ServerConfig; import org.kie.server.controller.api.model.spec.ServerTemplate; import org.kie.server.controller.api.model.spec.ServerTemplateKey; import org.kie.server.controller.api.service.NotificationService; import org.kie.server.controller.api.service.SpecManagementService; import org.kie.server.controller.api.storage.KieServerTemplateStorage; import org.kie.server.controller.impl.KieServerInstanceManager; import org.kie.server.controller.impl.storage.InMemoryKieServerTemplateStorage; public class SpecManagementServiceImpl implements SpecManagementService { private KieServerInstanceManager kieServerInstanceManager = KieServerInstanceManager.getInstance(); private KieServerTemplateStorage templateStorage = InMemoryKieServerTemplateStorage.getInstance(); private NotificationService notificationService = LoggingNotificationService.getInstance(); @Override public synchronized void saveContainerSpec( String serverTemplateId, ContainerSpec containerSpec ) { ServerTemplate serverTemplate = templateStorage.load( serverTemplateId ); if ( serverTemplate == null ) { throw new KieServerControllerNotFoundException( "No server template found for id " + serverTemplateId ); } if (serverTemplate.hasContainerSpec(containerSpec.getId())) { throw new KieServerControllerException( "Server template with id " + serverTemplateId + " associated already with container " + containerSpec.getId()); } // make sure correct server template is set containerSpec.setServerTemplateKey(new ServerTemplateKey(serverTemplate.getId(), serverTemplate.getName())); serverTemplate.addContainerSpec( containerSpec ); templateStorage.update( serverTemplate ); notificationService.notify( new ServerTemplateUpdated( serverTemplate ) ); if (containerSpec.getStatus().equals(KieContainerStatus.STARTED)) { List<Container> containers = kieServerInstanceManager.startContainer( serverTemplate, containerSpec ); notificationService.notify( serverTemplate, containerSpec, containers ); } } @Override public synchronized void updateContainerSpec( String serverTemplateId, ContainerSpec containerSpec ) { updateContainerSpec(serverTemplateId, containerSpec.getId(), containerSpec); } @Override public synchronized void updateContainerSpec(final String serverTemplateId, final String containerId, final ContainerSpec containerSpec) { ServerTemplate serverTemplate = templateStorage.load( serverTemplateId ); if ( serverTemplate == null ) { throw new KieServerControllerNotFoundException( "No server template found for id " + serverTemplateId ); } if( !containerSpec.getId().equals(containerId)) { throw new KieServerControllerException( "Cannot update container " + containerSpec.getId() + " on container " + containerId ); } if (!serverTemplate.hasContainerSpec(containerSpec.getId())) { throw new KieServerControllerNotFoundException( "Server template with id " + serverTemplateId + " has no container with id " + containerSpec.getId()); } if(!serverTemplate.hasMatchingId( containerSpec.getServerTemplateKey() )) { throw new KieServerControllerException( "Cannot change container template key during update."); } // make sure correct server template is set containerSpec.setServerTemplateKey(new ServerTemplateKey(serverTemplate.getId(), serverTemplate.getName())); ContainerSpec currentVersion = serverTemplate.getContainerSpec(containerSpec.getId()); serverTemplate.deleteContainerSpec(currentVersion.getId()); serverTemplate.addContainerSpec(containerSpec); templateStorage.update( serverTemplate ); notificationService.notify( new ServerTemplateUpdated( serverTemplate ) ); // in case container was started before it was update or update comes with status started update container in running servers if (currentVersion.getStatus().equals(KieContainerStatus.STARTED) || containerSpec.getStatus().equals(KieContainerStatus.STARTED)) { List<Container> containers = kieServerInstanceManager.upgradeContainer(serverTemplate, containerSpec); notificationService.notify(serverTemplate, containerSpec, containers); } } @Override public synchronized void saveServerTemplate( ServerTemplate serverTemplate ) { if ( templateStorage.exists( serverTemplate.getId() ) ) { templateStorage.update( serverTemplate ); } else { templateStorage.store( serverTemplate ); } notificationService.notify( new ServerTemplateUpdated( serverTemplate ) ); Collection<ContainerSpec> containerSpecs = serverTemplate.getContainersSpec(); if (containerSpecs != null && !containerSpecs.isEmpty()) { for (ContainerSpec containerSpec : containerSpecs) { if (containerSpec.getStatus().equals(KieContainerStatus.STARTED)) { List<Container> containers = kieServerInstanceManager.startContainer( serverTemplate, containerSpec ); notificationService.notify( serverTemplate, containerSpec, containers ); } } } } @Override public ServerTemplate getServerTemplate( String serverTemplateId ) { return templateStorage.load( serverTemplateId ); } @Override public Collection<ServerTemplateKey> listServerTemplateKeys() { return templateStorage.loadKeys(); } @Override public Collection<ServerTemplate> listServerTemplates() { return templateStorage.load(); } @Override public Collection<ContainerSpec> listContainerSpec( String serverTemplateId ) { ServerTemplate serverTemplate = templateStorage.load( serverTemplateId ); if ( serverTemplate == null ) { throw new KieServerControllerNotFoundException( "No server template found for id " + serverTemplateId ); } return serverTemplate.getContainersSpec(); } @Override public synchronized void deleteContainerSpec( String serverTemplateId, String containerSpecId ) { ServerTemplate serverTemplate = templateStorage.load( serverTemplateId ); if ( serverTemplate == null ) { throw new KieServerControllerNotFoundException( "No server template found for id " + serverTemplateId ); } if (serverTemplate.hasContainerSpec(containerSpecId)) { serverTemplate.deleteContainerSpec(containerSpecId); templateStorage.update(serverTemplate); notificationService.notify(new ServerTemplateUpdated(serverTemplate)); } else { throw new KieServerControllerNotFoundException("Container " + containerSpecId + " not found"); } } @Override public synchronized void deleteServerTemplate( String serverTemplateId ) { if ( !templateStorage.exists( serverTemplateId ) ) { throw new KieServerControllerNotFoundException( "No server template found for id " + serverTemplateId ); } templateStorage.delete( serverTemplateId ); notificationService.notify( new ServerTemplateDeleted( serverTemplateId ) ); } @Override public synchronized void copyServerTemplate( String serverTemplateId, String newServerTemplateId, String newServerTemplateName ) { final ServerTemplate serverTemplate = templateStorage.load( serverTemplateId ); if ( serverTemplate == null ) { throw new KieServerControllerNotFoundException( "No server template found for id " + serverTemplateId ); } final Map<Capability, ServerConfig> configMap = new HashMap<Capability, ServerConfig>( serverTemplate.getConfigs().size() ); for ( final Map.Entry<Capability, ServerConfig> entry : serverTemplate.getConfigs().entrySet() ) { configMap.put( entry.getKey(), copy( entry.getValue() ) ); } final Collection<ContainerSpec> containerSpecs = new ArrayList<ContainerSpec>( serverTemplate.getContainersSpec().size() ); for ( final ContainerSpec entry : serverTemplate.getContainersSpec() ) { containerSpecs.add( copy( entry, newServerTemplateId, newServerTemplateName ) ); } final ServerTemplate copy = new ServerTemplate( newServerTemplateId, newServerTemplateName, serverTemplate.getCapabilities(), configMap, containerSpecs ); templateStorage.store( copy ); } private ContainerSpec copy( final ContainerSpec origin, final String newServerTemplateId, final String newServerTemplateName ) { final Map<Capability, ContainerConfig> configMap = origin.getConfigs(); for ( Map.Entry<Capability, ContainerConfig> entry : origin.getConfigs().entrySet() ) { configMap.put( entry.getKey(), copy( entry.getValue() ) ); } return new ContainerSpec( origin.getId(), origin.getContainerName(), new ServerTemplateKey( newServerTemplateId, newServerTemplateName ), new ReleaseId( origin.getReleasedId() ), origin.getStatus(), configMap ); } private ContainerConfig copy( final ContainerConfig _value ) { if ( _value instanceof RuleConfig ) { final RuleConfig value = (RuleConfig) _value; return new RuleConfig( value.getPollInterval(), value.getScannerStatus() ); } else if ( _value instanceof ProcessConfig ) { final ProcessConfig value = (ProcessConfig) _value; return new ProcessConfig( value.getRuntimeStrategy(), value.getKBase(), value.getKSession(), value.getMergeMode() ); } return null; } private ServerConfig copy( final ServerConfig value ) { return new ServerConfig(); } @Override public synchronized void updateContainerConfig( String serverTemplateId, String containerSpecId, Capability capability, ContainerConfig containerConfig ) { ServerTemplate serverTemplate = templateStorage.load( serverTemplateId ); if ( serverTemplate == null ) { throw new KieServerControllerNotFoundException( "No server template found for id " + serverTemplateId ); } ContainerSpec containerSpec = serverTemplate.getContainerSpec( containerSpecId ); if ( containerSpec == null ) { throw new KieServerControllerNotFoundException( "No container spec found for id " + containerSpecId + " within server template with id " + serverTemplateId ); } containerSpec.getConfigs().put( capability, containerConfig ); templateStorage.update( serverTemplate ); notificationService.notify( new ServerTemplateUpdated( serverTemplate ) ); } @Override public synchronized void updateServerTemplateConfig( String serverTemplateId, Capability capability, ServerConfig serverTemplateConfig ) { ServerTemplate serverTemplate = templateStorage.load( serverTemplateId ); if ( serverTemplate == null ) { throw new KieServerControllerNotFoundException( "No server template found for id " + serverTemplateId ); } serverTemplate.getConfigs().put( capability, serverTemplateConfig ); templateStorage.update( serverTemplate ); notificationService.notify( new ServerTemplateUpdated( serverTemplate ) ); } @Override public synchronized void startContainer( ContainerSpecKey containerSpecKey ) { ServerTemplate serverTemplate = templateStorage.load( containerSpecKey.getServerTemplateKey().getId() ); if ( serverTemplate == null ) { throw new KieServerControllerNotFoundException( "No server template found for id " + containerSpecKey.getServerTemplateKey().getId() ); } final ContainerSpec containerSpec = serverTemplate.getContainerSpec( containerSpecKey.getId() ); if ( containerSpec == null ) { throw new KieServerControllerNotFoundException( "No container spec found for id " + containerSpecKey.getId() + " within server template with id " + serverTemplate.getId() ); } containerSpec.setStatus( KieContainerStatus.STARTED ); templateStorage.update( serverTemplate ); List<Container> containers = kieServerInstanceManager.startContainer( serverTemplate, containerSpec ); notificationService.notify( serverTemplate, containerSpec, containers ); } @Override public synchronized void stopContainer( ContainerSpecKey containerSpecKey ) { ServerTemplate serverTemplate = templateStorage.load( containerSpecKey.getServerTemplateKey().getId() ); if ( serverTemplate == null ) { throw new KieServerControllerNotFoundException( "No server template found for id " + containerSpecKey.getServerTemplateKey().getId() ); } ContainerSpec containerSpec = serverTemplate.getContainerSpec( containerSpecKey.getId() ); if ( containerSpec == null ) { throw new KieServerControllerNotFoundException( "No container spec found for id " + containerSpecKey.getId() + " within server template with id " + serverTemplate.getId() ); } containerSpec.setStatus( KieContainerStatus.STOPPED ); templateStorage.update( serverTemplate ); List<Container> containers = kieServerInstanceManager.stopContainer( serverTemplate, containerSpec ); notificationService.notify( serverTemplate, containerSpec, containers ); } public KieServerTemplateStorage getTemplateStorage() { return templateStorage; } public void setTemplateStorage( KieServerTemplateStorage templateStorage ) { this.templateStorage = templateStorage; } public NotificationService getNotificationService() { return notificationService; } public void setNotificationService( NotificationService notificationService ) { this.notificationService = notificationService; } public KieServerInstanceManager getKieServerInstanceManager() { return kieServerInstanceManager; } public void setKieServerInstanceManager( KieServerInstanceManager kieServerInstanceManager ) { this.kieServerInstanceManager = kieServerInstanceManager; } }