
de.fraunhofer.iese.ind2uce.reactive.ReactivePEP Maven / Gradle / Ivy
/*-
* =================================LICENSE_START=================================
* IND2UCE
* %%
* Copyright (C) 2016 Fraunhofer IESE (www.iese.fraunhofer.de)
* %%
* 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.
* =================================LICENSE_END=================================
*/
package de.fraunhofer.iese.ind2uce.reactive;
import de.fraunhofer.iese.ind2uce.api.component.exception.EvaluationUndecidableException;
import de.fraunhofer.iese.ind2uce.api.component.exception.InhibitException;
import de.fraunhofer.iese.ind2uce.api.component.interfaces.IPolicyEnforcementPoint;
import de.fraunhofer.iese.ind2uce.api.policy.AuthorizationDecision;
import de.fraunhofer.iese.ind2uce.api.policy.Event;
import de.fraunhofer.iese.ind2uce.pep.PolicyEnforcementPoint;
import de.fraunhofer.iese.ind2uce.reactive.common.RxPEPState;
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.apache.commons.lang3.tuple.Pair;
import java.io.IOException;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.concurrent.Callable;
import javax.annotation.concurrent.ThreadSafe;
import rx.Observable;
import rx.schedulers.Schedulers;
/**
* The Class RxPEP is one implementation for Reactive PEP.
*
* @param the generic type
*/
@ThreadSafe
public class ReactivePEP extends AbstractRxPEP {
private static final int MAX_RETRIES = 3;
/**
* Instantiates a new rx PEP.
*
* @param descriptionInterface the interface description
* @param policyEnforcementPoint the policy enforcement point
*/
public ReactivePEP(Class descriptionInterface, PolicyEnforcementPoint policyEnforcementPoint) {
super(policyEnforcementPoint, descriptionInterface);
}
/*
* (non-Javadoc)
* @see
* de.fraunhofer.iese.ind2uce.reactive.common.RxPEP#getPolicyEnforcementPoint(
* )
*/
@Override
public IPolicyEnforcementPoint getPolicyEnforcementPoint() {
if (this.isReady() != RxPEPState.REGISTRATION_DONE_SUCCESSFULLY) {
throw new IllegalStateException("Enforcement point is not yet registered at PMP");
}
return this.policyEnforcementPoint;
}
@Override
protected Object enforceDecision(Method method, Object[] args) {
// take the return type of the method as it can be Observable
// or Observable
final Type returnType = method.getGenericReturnType();
// check if it has type Observable && ParameterizedType.class.i
if (method.getReturnType() == Observable.class && returnType instanceof ParameterizedType) {
final Type genericType = ((ParameterizedType)returnType).getActualTypeArguments()[0];
if (genericType == Event.class) {
return ReactivePEP.this.enforceMethodForEvent(method, args);
} else if (genericType instanceof ParameterizedType && ((ParameterizedType)genericType).getRawType() == Pair.class && ((ParameterizedType)genericType).getActualTypeArguments().length == 2
&& ((ParameterizedType)genericType).getActualTypeArguments()[0] == Event.class && ((ParameterizedType)genericType).getActualTypeArguments()[1] == AuthorizationDecision.class) {
return ReactivePEP.this.getAuthorizationDecisionforEvent(method, args);
}
}
throw new IllegalStateException("Unknown error happened due to illegal declaration in ");
}
/**
* Enforce method for event.
*
* @param method the method
* @param objects the objects
* @return the observable
*/
private Observable enforceMethodForEvent(final Method method, final Object[] objects) {
return Observable.fromCallable(new Callable() {
@Override
public Event call() throws InhibitException, EvaluationUndecidableException, IOException {
final Event event = ReactivePEP.this.readAndCreateEvent(method, objects);
ReactivePEP.this.policyEnforcementPoint.enforce(event);
return event;
}
})
// .retryWhen(errors -> errors.filter(o -> ((o.getCause() instanceof
// HttpErrorCause) && (((HttpErrorCause)o.getCause()).getErrorCode() ==
// HttpStatus.SC_SERVICE_UNAVAILABLE)))
// .zipWith(Observable.range(1, MAX_RETRIES), (n, i) -> i) // retry on
// // http
// // error 503
// .flatMap(retryCount -> Observable.timer(1,
// TimeUnit.MILLISECONDS)).subscribeOn(Schedulers.io()))
// TODO
.doOnError(throwable -> Observable.error(throwable));
}
/**
* Gets authorization decision for event.
*
* @param method the method
* @param objects the method arguments
* @return the events and authorization decisions
*/
private Observable> getAuthorizationDecisionforEvent(Method method, Object[] objects) {
return Observable.fromCallable(() -> {
final Event event = this.readAndCreateEvent(method, objects);
return new ImmutablePair<>(event, this.policyEnforcementPoint.getDecision(event));
}).subscribeOn(Schedulers.io());
}
@Override
protected void postSuccessfulRegistration() {
// Intended blank
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy