001/*
002* The contents of this file are subject to the terms of the Common Development and
003* Distribution License (the License). You may not use this file except in compliance with the
004* License.
005*
006* You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
007* specific language governing permission and limitations under the License.
008*
009* When distributing Covered Software, include this CDDL Header Notice in each file and include
010* the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
011* Header, with the fields enclosed by brackets [] replaced by your own identifying
012* information: "Portions copyright [year] [name of copyright owner]".
013*
014* Copyright 2015 ForgeRock AS.
015*/
016package org.forgerock.openig.handler.router;
017
018import static org.forgerock.audit.AuditServiceBuilder.newAuditService;
019import static org.forgerock.audit.json.AuditJsonConfig.registerHandlerToService;
020import static org.forgerock.http.HttpApplication.LOGGER;
021import static org.forgerock.openig.el.Bindings.bindings;
022
023import org.forgerock.audit.AuditException;
024import org.forgerock.audit.AuditService;
025import org.forgerock.audit.AuditServiceBuilder;
026import org.forgerock.audit.AuditServiceConfiguration;
027import org.forgerock.audit.DependencyProvider;
028import org.forgerock.audit.json.AuditJsonConfig;
029import org.forgerock.audit.providers.DefaultLocalHostNameProvider;
030import org.forgerock.audit.providers.LocalHostNameProvider;
031import org.forgerock.audit.providers.ProductInfoProvider;
032import org.forgerock.json.JsonValue;
033import org.forgerock.json.resource.ResourceException;
034import org.forgerock.json.resource.ServiceUnavailableException;
035import org.forgerock.openig.el.ExpressionException;
036import org.forgerock.openig.el.Expressions;
037import org.forgerock.openig.heap.GenericHeapObject;
038import org.forgerock.openig.heap.GenericHeaplet;
039import org.forgerock.openig.heap.HeapException;
040
041/**
042 * Constructs an {@link AuditService} through an {@link Heaplet}.
043 */
044public class AuditServiceObject extends GenericHeapObject {
045
046    /** Creates and initializes an AuditService in a heap environment. */
047    public static class Heaplet extends GenericHeaplet {
048
049        private AuditService auditService;
050
051        @Override
052        public Object create() throws HeapException {
053            try {
054                JsonValue evaluatedConfiguration = new JsonValue(Expressions.evaluate(config.asMap(), bindings()));
055                auditService = buildAuditService(evaluatedConfiguration);
056                return auditService;
057            } catch (AuditException | ResourceException | ExpressionException ex) {
058                throw new HeapException(ex);
059            }
060        }
061
062        @Override
063        public void start() throws HeapException {
064            super.start();
065            if (auditService != null) {
066                try {
067                    auditService.startup();
068                } catch (ServiceUnavailableException ex) {
069                    throw new HeapException(ex);
070                }
071            }
072        }
073
074        @Override
075        public void destroy() {
076            super.destroy();
077            if (auditService != null) {
078                auditService.shutdown();
079            }
080        }
081
082        /** Loads the audit service configuration from JSON. */
083        private AuditService buildAuditService(JsonValue config)
084                throws AuditException, ServiceUnavailableException, ResourceException {
085            final JsonValue auditServiceConfig = config.get("config");
086
087            final AuditServiceConfiguration auditServiceConfiguration;
088            if (auditServiceConfig.isNotNull()) {
089                auditServiceConfiguration = AuditJsonConfig.parseAuditServiceConfiguration(auditServiceConfig);
090            } else {
091                auditServiceConfiguration = new AuditServiceConfiguration();
092            }
093            AuditServiceBuilder auditServiceBuilder = newAuditService();
094            auditServiceBuilder.withConfiguration(auditServiceConfiguration);
095            auditServiceBuilder.withDependencyProvider(new GatewayDependencyProvider());
096
097            final ClassLoader classLoader = this.getClass().getClassLoader();
098            for (final JsonValue handlerConfig : config.get("event-handlers")) {
099                try {
100                    registerHandlerToService(handlerConfig, auditServiceBuilder, classLoader);
101                } catch (Exception ex) {
102                    LOGGER.error("Unable to register handler defined by config: " + handlerConfig, ex);
103                }
104            }
105
106            return auditServiceBuilder.build();
107        }
108
109    }
110
111    private static class GatewayDependencyProvider implements DependencyProvider {
112
113        private final LocalHostNameProvider localHostNameProvider = new DefaultLocalHostNameProvider();
114
115        private final ProductInfoProvider productInfoProvider = new ProductInfoProvider() {
116
117            @Override
118            public String getProductName() {
119                return "OpenIG";
120            }
121        };
122
123        @Override
124        public <T> T getDependency(Class<T> type) throws ClassNotFoundException {
125            if (LocalHostNameProvider.class.equals(type)) {
126                return type.cast(localHostNameProvider);
127            } else if (ProductInfoProvider.class.equals(type)) {
128                return type.cast(productInfoProvider);
129            }
130            throw new ClassNotFoundException(type.getName());
131        }
132    }
133}