/*
* 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;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.CopyOnWriteArraySet;
import org.kie.internal.identity.IdentityProvider;
import org.kie.server.api.KieServerEnvironment;
import org.kie.server.api.model.KieContainerResource;
import org.kie.server.api.model.KieContainerStatus;
import org.kie.server.api.model.KieServerConfig;
import org.kie.server.services.api.ContainerLocator;
import org.kie.server.services.api.KieServerExtension;
import org.kie.server.services.api.KieServerRegistry;
import org.kie.server.services.impl.storage.KieServerState;
import org.kie.server.services.impl.storage.KieServerStateRepository;
public class KieServerRegistryImpl implements KieServerRegistry {
private final ConcurrentMap<String, KieContainerInstanceImpl> containers = new ConcurrentHashMap<String, KieContainerInstanceImpl>();
private final ConcurrentMap<String, List<KieContainerInstanceImpl>> containersByAlias = new ConcurrentHashMap<String, List<KieContainerInstanceImpl>>();
private IdentityProvider identityProvider;
private ConcurrentMap<String, KieServerExtension> serverExtensions = new ConcurrentHashMap<String, KieServerExtension>();
private Set<String> controllers = new CopyOnWriteArraySet<String>();
private Set<Class<?>> extraClasses = new HashSet<>();
private KieServerStateRepository repository;
private KieSessionLookupManager kieSessionLookupManager = new KieSessionLookupManager();
@Override
public KieContainerInstanceImpl registerContainer(String id, KieContainerInstanceImpl kieContainerInstance) {
synchronized ( containers ) {
KieContainerInstanceImpl kci = containers.putIfAbsent(id, kieContainerInstance);
if( kci != null && kci.getStatus() == KieContainerStatus.FAILED ) {
// if previous container failed, allow override
containers.put(id, kieContainerInstance);
registerWithAlias(kieContainerInstance);
return null;
}
registerWithAlias(kieContainerInstance);
return kci;
}
}
@Override
public KieContainerInstanceImpl unregisterContainer(String id) {
KieContainerInstanceImpl containerInstance = containers.remove(id);
removeFromAlias(containerInstance);
return containerInstance;
}
@Override
public KieContainerInstanceImpl getContainer(String id) {
return containers.get(id);
}
@Override
public KieContainerInstanceImpl getContainer(String alias, ContainerLocator locator) {
KieContainerInstanceImpl containerInstance = getContainer(alias);
if (containerInstance == null) {
String containerId = locator.locateContainer(alias, containersByAlias.getOrDefault(alias, new ArrayList<KieContainerInstanceImpl>()));
if (containerId == null) {
throw new IllegalArgumentException("Cannot find container for alias '" + alias + "'");
}
return getContainer(containerId);
}
return containerInstance;
}
@Override
public String getContainerId(String alias, ContainerLocator locator) {
KieContainerInstanceImpl kieContainerInstance = getContainer(alias, locator);
if (kieContainerInstance == null) {
return alias;
}
return kieContainerInstance.getContainerId();
}
@Override
public List<KieContainerInstanceImpl> getContainers() {
return new ArrayList<KieContainerInstanceImpl>(containers.values());
}
@Override
public List<String> getContainerAliases() {
return new ArrayList<String>(containersByAlias.keySet());
}
@Override
public List<KieContainerInstanceImpl> getContainersForAlias(String alias) {
return new ArrayList<KieContainerInstanceImpl>(containersByAlias.getOrDefault(alias, new ArrayList<KieContainerInstanceImpl>()));
}
@Override
public void registerIdentityProvider(IdentityProvider identityProvider) {
this.identityProvider = identityProvider;
}
@Override
public IdentityProvider unregisterIdentityProvider() {
IdentityProvider unregistered = this.identityProvider;
this.identityProvider = null;
return unregistered;
}
@Override
public IdentityProvider getIdentityProvider() {
return this.identityProvider;
}
@Override
public void registerServerExtension(KieServerExtension kieServerExtension) {
this.serverExtensions.putIfAbsent(kieServerExtension.getExtensionName(), kieServerExtension);
}
@Override
public void unregisterServerExtension(KieServerExtension kieServerExtension) {
this.serverExtensions.remove(kieServerExtension.getExtensionName());
}
@Override
public List<KieServerExtension> getServerExtensions() {
List<KieServerExtension> extensions = new ArrayList<KieServerExtension>(serverExtensions.values());
Collections.sort(extensions, new Comparator<KieServerExtension>() {
@Override
public int compare(KieServerExtension e1, KieServerExtension e2) {
return e1.getStartOrder().compareTo(e2.getStartOrder());
}
});
return extensions;
}
@Override
public KieServerExtension getServerExtension(String extensionName) {
return serverExtensions.get(extensionName);
}
@Override
public void registerController(String controllerUrl) {
this.controllers.add(controllerUrl);
}
@Override
public Set<String> getControllers() {
return new HashSet<String>(controllers);
}
@Override
public void registerStateRepository(KieServerStateRepository repository) {
this.repository = repository;
}
@Override
public KieServerStateRepository getStateRepository() {
return this.repository;
}
@Override
public KieSessionLookupManager getKieSessionLookupManager() {
return kieSessionLookupManager;
}
@Override
public KieServerConfig getConfig() {
KieServerState currentState = repository.load(KieServerEnvironment.getServerId());
return currentState.getConfiguration();
}
protected void registerWithAlias(KieContainerInstanceImpl kieContainerInstance) {
KieContainerResource containerResource = kieContainerInstance.getResource();
String alias = getContainerAlias(containerResource);
List<KieContainerInstanceImpl> byAlias = containersByAlias.get(alias);
if (byAlias == null) {
byAlias = new ArrayList<>();
containersByAlias.put(alias, byAlias);
}
byAlias.add(kieContainerInstance);
}
protected void removeFromAlias(KieContainerInstanceImpl kieContainerInstance) {
if (kieContainerInstance == null) {
return;
}
KieContainerResource containerResource = kieContainerInstance.getResource();
String alias = getContainerAlias(containerResource);
List<KieContainerInstanceImpl> byAlias = containersByAlias.get(alias);
if (byAlias != null) {
byAlias.remove(kieContainerInstance);
}
}
protected String getContainerAlias(KieContainerResource containerResource) {
String alias = containerResource.getContainerAlias();
if (alias == null || alias.isEmpty()) {
alias = containerResource.getReleaseId().getArtifactId();
}
return alias;
}
@Override
public void addExtraClasses(Set<Class<?>> extraClasses) {
this.extraClasses.addAll(extraClasses);
}
@Override
public Set<Class<?>> getExtraClasses() {
return extraClasses;
}
}