Package com.opengamma.bbg.livedata

Source Code of com.opengamma.bbg.livedata.BloombergEntitlementChecker

/**
* Copyright (C) 2009 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.bbg.livedata;

import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.BlockingQueue;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.bloomberglp.blpapi.CorrelationID;
import com.bloomberglp.blpapi.Element;
import com.bloomberglp.blpapi.Request;
import com.bloomberglp.blpapi.UserHandle;
import com.google.common.collect.Sets;
import com.opengamma.OpenGammaRuntimeException;
import com.opengamma.bbg.AbstractBloombergStaticDataProvider;
import com.opengamma.bbg.BloombergConnector;
import com.opengamma.bbg.BloombergConstants;
import com.opengamma.bbg.referencedata.ReferenceData;
import com.opengamma.bbg.referencedata.ReferenceDataProvider;
import com.opengamma.bbg.referencedata.ReferenceDataProviderGetRequest;
import com.opengamma.bbg.referencedata.ReferenceDataProviderGetResult;
import com.opengamma.bbg.util.BloombergDomainIdentifierResolver;
import com.opengamma.livedata.LiveDataSpecification;
import com.opengamma.livedata.UserPrincipal;
import com.opengamma.livedata.entitlement.LiveDataEntitlementChecker;
import com.opengamma.livedata.resolver.DistributionSpecificationResolver;
import com.opengamma.livedata.server.DistributionSpecification;
import com.opengamma.util.ArgumentChecker;

import net.sf.ehcache.Cache;

/**
* Checks that the user has entitlement to access Bloomberg.
* <p>
* To understand what's going on this class, read Bloomberg Server API 3.0 Developer Guide, Chapter 7.
*/
public class BloombergEntitlementChecker extends AbstractBloombergStaticDataProvider implements LiveDataEntitlementChecker {

  /** Logger. */
  private static final Logger s_logger = LoggerFactory.getLogger(BloombergEntitlementChecker.class);
  /**
   * The length of half a day in seconds.
   */
  private static final long HALF_A_DAY_IN_SECONDS = 12 * 60 * 60;

  /**
   * The Bloomberg reference data provider.
   */
  private final ReferenceDataProvider _refDataProvider;
  /**
   * Cache: UserPrincipal -> UserHandle
   */
  private final Cache _userHandleCache;
  /**
   * Cache: DistributionSpecification -> com.bloomberglp.blpapi.Element (containing Bloomberg Entitlement IDs)
   */
  private final Cache _eidCache;
  /**
   * The distribution resolver.
   */
  private final DistributionSpecificationResolver _resolver;

  /**
   * Creates an instance.
   *
   * @param bloombergConnector  the Bloomberg connector, not null
   * @param referenceDataProvider  the reference data provider, not null
   * @param resolver  the resolver, not null
   */
  public BloombergEntitlementChecker(
      BloombergConnector bloombergConnector,
      ReferenceDataProvider referenceDataProvider,
      DistributionSpecificationResolver resolver) {
    super(bloombergConnector, BloombergConstants.AUTH_SVC_NAME);
    ArgumentChecker.notNull(referenceDataProvider, "referenceDataProvider");
    ArgumentChecker.notNull(resolver, "resolver");
   
    _refDataProvider = referenceDataProvider;
    _resolver = resolver;
   
    // Cache will contain max 100 entries, each of which will expire in 12 hours 
    _userHandleCache = new Cache("Bloomberg user handle cache", 100, false, false, HALF_A_DAY_IN_SECONDS, HALF_A_DAY_IN_SECONDS);
    _userHandleCache.initialise();
   
    // Cache will contain max 100 entries, each of which will expire in 12 hours
    _eidCache = new Cache("Bloomberg EID cache", 100, false, false, HALF_A_DAY_IN_SECONDS, HALF_A_DAY_IN_SECONDS);
    _eidCache.initialise();
  }

  @Override
  protected Logger getLogger() {
    return s_logger;
  }

  //-------------------------------------------------------------------------
  @Override
  public Map<LiveDataSpecification, Boolean> isEntitled(UserPrincipal user, Collection<LiveDataSpecification> requestedSpecifications) {
    Map<LiveDataSpecification, Boolean> returnValue = new HashMap<>();
    for (LiveDataSpecification spec : requestedSpecifications) {
      boolean entitled = isEntitled(user,  spec);
      returnValue.put(spec, entitled);                 
    }
    return returnValue;
  }

  @Override
  public boolean isEntitled(UserPrincipal user, LiveDataSpecification requestedSpecification) {
    DistributionSpecification distributionSpecification = _resolver.resolve(requestedSpecification);
    return isEntitled(user, distributionSpecification);
  }

  //-------------------------------------------------------------------------
  public boolean isEntitled(UserPrincipal user, DistributionSpecification distributionSpec) {
    UserHandle userHandle = getUserHandle(user);
    if (userHandle == null) {
      return false;
    }
   
    Element neededEntitlements = getEids(distributionSpec);
    if (neededEntitlements == null) {
      return true;
    }
   
    boolean isEntitled = userHandle.hasEntitlements(neededEntitlements, getService());
    return isEntitled;
  }

  private UserHandle getUserHandle(UserPrincipal user) {
    net.sf.ehcache.Element cachedUserHandle = _userHandleCache.get(user);
    if (cachedUserHandle == null) {
      Request authorizationRequest = getService().createAuthorizationRequest();
     
      Integer uuid;
      try {
        uuid = Integer.parseInt(user.getUserName());
      } catch (NumberFormatException e) {
        s_logger.info("Bloomberg user IDs are integers - so " + user.getUserName() + " cannot be entitled to anything");       
        return null;
      }
     
      authorizationRequest.set("uuid", uuid);
      authorizationRequest.set("ipAddress", user.getIpAddress());
      UserHandle userHandle = getSession().createUserHandle();
     
      CorrelationID cid = submitBloombergAuthorizationRequest(authorizationRequest, userHandle);
      BlockingQueue<Element> resultElements = getResultElement(cid);
      if (resultElements == null || resultElements.isEmpty()) {
        s_logger.info("Unable to get authorization info from Bloomberg for {}", user);
        return null;
      }
     
      boolean authorizedSuccessfully = false;
      for (Element resultElem : resultElements) {
        if (resultElem.name().equals(BloombergConstants.AUTHORIZATION_SUCCESS)) {
          cachedUserHandle = new net.sf.ehcache.Element(user, userHandle);
          _userHandleCache.put(cachedUserHandle);
          authorizedSuccessfully = true;         
         
        } else if (resultElem.name().equals(BloombergConstants.AUTHORIZATION_FAILURE)) {
          Element reasonElem = resultElem.getElement(BloombergConstants.REASON);
          s_logger.info("Bloomberg authorization failed {}", reasonElem);
         
        } else {
          s_logger.info("Bloomberg authorization result {}", resultElem);
        }
      }
     
      if (!authorizedSuccessfully) {
        return null;
      }
    }
   
    UserHandle userHandle = (UserHandle) cachedUserHandle.getObjectValue();
    return userHandle;
  }

  private Element getEids(DistributionSpecification distributionSpec) {
    net.sf.ehcache.Element cachedEids = _eidCache.get(distributionSpec);
    if (cachedEids == null) {
      String lookupKey = BloombergDomainIdentifierResolver.toBloombergKey(distributionSpec.getMarketDataId());
      Set<String> fields = Sets.newHashSet(
          BloombergConstants.FIELD_ID_BBG_UNIQUE, // TODO, this is necessary because otherwise the request would not get any real fields
          BloombergConstants.FIELD_EID_DATA);
      ReferenceDataProviderGetRequest rdRequest = ReferenceDataProviderGetRequest.createGet(Collections.singleton(lookupKey), fields, true);
      ReferenceDataProviderGetResult refData = _refDataProvider.getReferenceData(rdRequest);
     
      ReferenceData result = refData.getReferenceData(lookupKey);
      if (result.getErrors().size() > 0) {
        throw new OpenGammaRuntimeException("Error while obtaining entitlement information: " + lookupKey);
      }
      Element eids = result.getEntitlementInfo();
     
      cachedEids = new net.sf.ehcache.Element(distributionSpec, eids);
      _eidCache.put(cachedEids);
    }
   
    Element neededEntitlements = (Element) cachedEids.getObjectValue();
    return neededEntitlements;
  }

}
TOP

Related Classes of com.opengamma.bbg.livedata.BloombergEntitlementChecker

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.