/* * 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. * You may obtain a copy of the License at * * 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.guvnor.ala.registry.local; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Optional; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CopyOnWriteArrayList; import javax.enterprise.context.ApplicationScoped; import org.guvnor.ala.registry.RuntimeRegistry; import org.guvnor.ala.registry.local.utils.PageSortUtils; import org.guvnor.ala.runtime.Runtime; import org.guvnor.ala.runtime.RuntimeId; import org.guvnor.ala.runtime.providers.Provider; import org.guvnor.ala.runtime.providers.ProviderId; import org.guvnor.ala.runtime.providers.ProviderType; import static org.uberfire.commons.validation.PortablePreconditions.*; /** * @TODO: This is an implementation for local testing. A * more robust and distributed implementation should be provided for real * use cases. All the lookups mechanisms and structures needs to be improved for * performance. */ @ApplicationScoped public class InMemoryRuntimeRegistry implements RuntimeRegistry { private final Map<String, ProviderType> providerTypes; private final Map<String, Provider> providers; private final Map<ProviderType, List<Provider>> providersByType; private final Map<ProviderType, List<Runtime>> runtimesByProviderType; public InMemoryRuntimeRegistry() { providerTypes = new ConcurrentHashMap<>(); providers = new ConcurrentHashMap<>(); providersByType = new ConcurrentHashMap<>(); runtimesByProviderType = new ConcurrentHashMap<>(); } @Override public void registerProviderType( ProviderType pt ) { providerTypes.put( pt.getProviderTypeName(), pt ); } @Override public List<ProviderType> getProviderTypes( Integer page, Integer pageSize, String sort, boolean sortOrder ) { Collection<ProviderType> values = providerTypes.values(); return PageSortUtils.pageSort( values, (ProviderType pt1, ProviderType pt2) -> { switch ( sort ) { case "providerTypeName": return pt1.getProviderTypeName().compareTo( pt2.getProviderTypeName() ); case "version": return pt1.getVersion().compareTo( pt2.getVersion() ); default: return pt1.toString().compareTo( pt2.toString() ); } }, page, pageSize, sort, sortOrder ); } @Override public ProviderType getProviderType( String provider ) { return providerTypes.get( provider ); } @Override public void unregisterProviderType( ProviderType providerType ) { providerTypes.remove( providerType.getProviderTypeName() ); } @Override public void registerProvider( Provider provider ) { providers.put( provider.getId(), provider ); if ( providersByType.get( provider.getProviderType() ) != null ) { List<Provider> providersInType = providersByType.get( provider.getProviderType() ); for ( Provider p : providersInType ) { if ( p.getId().equals( provider.getId() ) ) { providersInType.remove( p ); } } } providersByType.computeIfAbsent( provider.getProviderType(), providerType -> new CopyOnWriteArrayList<>() ) .add( provider ); } @Override public List<Provider> getProviders( Integer page, Integer pageSize, String sort, boolean sortOrder ) { Collection<Provider> values = providers.values(); return PageSortUtils.pageSort( values, (Provider p1, Provider p2) -> { switch ( sort ) { case "id": return p1.getId().compareTo( p2.getId() ); case "providerTypeName": return p1.getProviderType().getProviderTypeName().compareTo( p2.getProviderType().getProviderTypeName() ); case "version": return p1.getProviderType().getVersion().compareTo( p2.getProviderType().getVersion() ); default: return p1.toString().compareTo( p2.toString() ); } }, page, pageSize, sort, sortOrder ); } @Override public List<Provider> getProvidersByType( ProviderType type ) { return providersByType.getOrDefault( type, Collections.emptyList() ); } @Override public Provider getProvider( String providerName ) { return providers.get( providerName ); } @Override public void unregisterProvider( Provider provider ) { List<Provider> filteredProviders = providersByType.get( provider.getProviderType() ); if ( filteredProviders != null ) { filteredProviders.remove( provider ); } providers.remove( provider.getId() ); } @Override public void unregisterProvider( String providerName ) { for ( Provider p : providers.values() ) { if ( p.getId().equals( providerName ) ) { unregisterProvider( p ); } } } @Override public void registerRuntime( Runtime runtime ) { final Provider provider = providers.get( runtime.getProviderId().getId() ); if ( runtimesByProviderType.get( provider.getProviderType() ) != null ) { List<Runtime> runtimes = runtimesByProviderType.get( provider.getProviderType() ); for ( Runtime r : runtimes ) { if ( r.getId().equals( runtime.getId() ) ) { runtimes.remove( r ); } } } runtimesByProviderType.computeIfAbsent( provider.getProviderType(), providerType -> new CopyOnWriteArrayList<>() ) .add( runtime ); } @Override public List<Runtime> getRuntimes( Integer page, Integer pageSize, String sort, boolean sortOrder ) { List<Runtime> runtimes = new ArrayList<>(); for ( List<Runtime> rs : runtimesByProviderType.values() ) { runtimes.addAll( rs ); } return PageSortUtils.pageSort( runtimes, (Runtime r1, Runtime r2) -> { switch ( sort ) { case "id": return r1.getId().compareTo( r2.getId() ); case "state": return r1.getState().getState().compareTo( r2.getState().getState() ); default: return r1.toString().compareTo( r2.toString() ); } }, page, pageSize, sort, sortOrder ); } @Override public List<Runtime> getRuntimesByProvider( ProviderType providerType ) { return new ArrayList<>( runtimesByProviderType.get( providerType ) ); } @Override public Runtime getRuntimeById( String id ) { for ( ProviderType pt : runtimesByProviderType.keySet() ) { for ( Runtime r : runtimesByProviderType.get( pt ) ) { if ( r.getId().equals( id ) ) { return r; } } } return null; } @Override public <T extends Provider> Optional<T> getProvider( final ProviderId providerId, final Class<T> clazz ) { checkNotNull( "providerId", providerId ); checkNotNull( "clazz", clazz ); final Provider value = providers.get( providerId.getId() ); return Optional.ofNullable( value ) .filter( provider -> clazz.isInstance( provider ) ) .map( provider -> clazz.cast( provider ) ); } @Override public void unregisterRuntime( final RuntimeId runtime ) { final Provider provider = providers.get( runtime.getProviderId().getId() ); List<Runtime> filteredRuntimes = runtimesByProviderType.get( provider.getProviderType() ); if ( filteredRuntimes != null ) { filteredRuntimes.remove( runtime ); } } }