/* * Copyright (c) 2014-2015 Janith Bandara, This source is a part of * Audit4j - An open source auditing framework. * http://audit4j.org * * 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.audit4j.core.io; import java.lang.reflect.Method; import org.audit4j.core.AnnotationTransformer; import org.audit4j.core.dto.AnnotationAuditEvent; import org.audit4j.core.dto.AuditEvent; import reactor.core.Environment; import reactor.core.composable.Deferred; import reactor.core.composable.Stream; import reactor.core.composable.spec.Streams; import reactor.function.Consumer; import reactor.function.support.Boundary; /** * The Class AnnotationAuditOutputStream. * * @author <a href="mailto:janith3000@gmail.com">Janith Bandara</a> * * @since 2.0.0 */ public class AsyncAnnotationAuditOutputStream implements AuditOutputStream<AnnotationAuditEvent>{ /** The output stream. */ AuditOutputStream<AuditEvent> outputStream; /** The annotation deferred. */ Deferred<AnnotationAuditEvent, Stream<AnnotationAuditEvent>> annotationDeferred = null; /** The Constant ENV. */ static Environment ENV ; /** The b. */ Boundary b = null; /** * Instantiates a new annotation audit output stream. * * @param outputStream the output stream * @param transformer the transformer */ public AsyncAnnotationAuditOutputStream(final AuditOutputStream<AuditEvent> outputStream, final AnnotationTransformer transformer) { ENV = new Environment(); this.outputStream = outputStream; b = new Boundary(); annotationDeferred = Streams.<AnnotationAuditEvent> defer().env(ENV).dispatcher(Environment.RING_BUFFER).get(); Stream<AnnotationAuditEvent> annostream = annotationDeferred.compose(); annostream.consume(b.bind(new Consumer<AnnotationAuditEvent>() { @Override public void accept(AnnotationAuditEvent annotationEvent) { AuditEvent event = transformer.transformToEvent(annotationEvent); // event is null if annotation is not found if (event != null) { outputStream.write(event); } } })); } /** * Write. * * @param event * the event * @return the annotation audit output stream */ @Override public AsyncAnnotationAuditOutputStream write(AnnotationAuditEvent event) { annotationDeferred.accept(event); b.await(); return this; } /** * Write. * * @param clazz * the clazz * @param method * the method * @param args * the args * @return the annotation audit output stream */ public AsyncAnnotationAuditOutputStream write(Class<?> clazz, Method method, Object[] args) { AnnotationAuditEvent event = new AnnotationAuditEvent(); event.setClazz(clazz); event.setMethod(method); event.setArgs(args); annotationDeferred.accept(event); b.await(); return this; } /** * Close. */ @Override public void close() { ENV.shutdown(); if (outputStream != null) { outputStream.close(); } } /* * (non-Javadoc) * * @see java.lang.Object#clone() */ @Override public Object clone() { return null; } }