/* * Copyright 2015 Red Hat, Inc. and/or its affiliates * and other contributors as indicated by the @author tags. * * 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.hawkular.inventory.cdi; import static org.hawkular.inventory.cdi.Log.LOG; import java.io.IOException; import java.io.Reader; import java.util.HashMap; import java.util.Map; import java.util.Properties; import java.util.ServiceLoader; import javax.enterprise.event.Event; import javax.enterprise.inject.Disposes; import javax.enterprise.inject.Instance; import javax.enterprise.inject.Produces; import javax.inject.Inject; import javax.inject.Singleton; import org.hawkular.inventory.api.Configuration; import org.hawkular.inventory.api.Inventory; import org.hawkular.inventory.api.feeds.AcceptWithFallbackFeedIdStrategy; import org.hawkular.inventory.api.feeds.RandomUUIDFeedIdStrategy; /** * @author Lukas Krejci * @since 0.0.2 */ @Singleton public class OfficialInventoryProducer { public static final Configuration.Property IMPL_PROPERTY = Configuration.Property.builder() .withPropertyNameAndSystemProperty("hawkular.inventory.impl") .withEnvironmentVariables("HAWKULAR_INVENTORY_IMPL").build(); @Inject private Event<InventoryInitialized> inventoryInitializedEvent; @Inject private Event<DisposingInventory> disposingInventoryEvent; @Inject private Instance<InventoryConfigurationData> configData; @Produces @Singleton @Official public Inventory getInventory() throws InterruptedException { Inventory inventory = initInventory(); inventoryInitializedEvent.fire(new InventoryInitialized(inventory)); return inventory; } public void close(@Disposes @Official Inventory inventory) throws Exception { disposingInventoryEvent.fire(new DisposingInventory(inventory)); dispose(inventory); } private Inventory initInventory() throws InterruptedException { Map<String, String> config = new HashMap<>(); if (!configData.isUnsatisfied()) { Properties conf = new Properties(); try (Reader rdr = configData.get().open()) { conf.load(rdr); } catch (IOException e) { LOG.wCannotReadConfigurationFile(null, e); } conf.forEach((k, v) -> config.put(k.toString(), v == null ? null : v.toString())); } Configuration cfg = Configuration.builder() .withFeedIdStrategy(new AcceptWithFallbackFeedIdStrategy(new RandomUUIDFeedIdStrategy())) //.withResultFilter(securityIntegration) results filtering not required for the current // security model .withConfiguration(config).build(); Inventory inventory = instantiateNew(cfg); LOG.iUsingImplementation(inventory.getClass().getName()); int failures = 0; int maxFailures = 15; boolean initialized = false; Throwable lastError = null; while (!initialized && failures++ < maxFailures) { try { inventory.initialize(cfg); initialized = true; } catch (Throwable e) { LOG.debug("Unable to initialize inventory, exception thrown: ", e); LOG.wInitializationFailure(failures, maxFailures, e.getMessage()); lastError = e; Thread.sleep(3000); } } if (!initialized) { //noinspection ConstantConditions throw new IllegalStateException("Could not initialize inventory. Last error message was: " + lastError.getMessage(), lastError); } LOG.iInitialized(); return inventory; } private void dispose(Inventory inventory) throws Exception { if (inventory != null) { inventory.close(); } } private Inventory instantiateNew(Configuration config) { String implClass = config.getProperty(IMPL_PROPERTY, null); if (implClass != null) { try { return (Inventory) Class.forName(implClass).newInstance(); } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) { throw new IllegalStateException("Failed to instantiate inventory using class '" + implClass + "'.", e); } } else { return ServiceLoader.load(Inventory.class).iterator().next(); } } }