/******************************************************************************* * Copyright (c) 2006-2010 eBay Inc. All Rights Reserved. * 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 *******************************************************************************/ /** * */ package org.ebayopensource.turmeric.runtime.common.cachepolicy; import java.io.ByteArrayInputStream; import java.io.InputStream; import java.net.URL; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; import org.ebayopensource.turmeric.runtime.common.exceptions.ErrorDataFactory; import org.ebayopensource.turmeric.runtime.common.exceptions.ServiceException; import org.ebayopensource.turmeric.runtime.common.service.ServiceOperationDesc; import org.ebayopensource.turmeric.runtime.common.service.ServiceOperationParamDesc; import org.ebayopensource.turmeric.runtime.common.types.SOAConstants; import org.ebayopensource.turmeric.runtime.common.utils.Preconditions; import org.ebayopensource.turmeric.runtime.errorlibrary.ErrorConstants; import org.ebayopensource.turmeric.runtime.sif.impl.internal.service.ClientServiceDesc; import org.ebayopensource.turmeric.runtime.sif.service.ClientServiceId; import org.ebayopensource.turmeric.runtime.sif.service.Service; import org.ebayopensource.turmeric.runtime.sif.service.ServiceFactory; /** * This class provides the initialization/loading of the cache policy on the * client side. * * @author rpallikonda * */ public abstract class BaseCachePolicyProvider implements CacheProvider { /** * Flag to capture the initialization status */ private enum STATUS { UNINITIALIZED, INIT_FAILED, INIT_SUCCESS } private STATUS m_status = STATUS.UNINITIALIZED ; /** * An object to hold CachePolicy meta data for a service. */ protected CachePolicyDesc m_desc; /* (non-Javadoc) * @see org.ebayopensource.turmeric.runtime.common.service.CacheProvider#init(ClientServiceDesc serviceDesc) */ /** * init method. * It does the following: * 1. Fetches the cache policy definition from the server side * 2. Loads the policy * 3. Creates the cache policy desc * * @param serviceDesc client service desc for the service * @param serviceURL service end-point (optional) * @throws ServiceException Exception when initialization fails. */ public synchronized void init(ClientServiceDesc serviceDesc, URL serviceURL) throws ServiceException { if (m_status != STATUS.UNINITIALIZED) return; Preconditions.checkNotNull(serviceDesc); InputStream in = null; if (serviceURL == null ) { serviceURL = serviceDesc.getDefServiceLocationURL(); } try { in = fetchCachePolicy(serviceDesc.getServiceId(), serviceURL); throwErrorOnNull(in); CachePolicyHolder holder = CachePolicyHolder.loadCachePolicy(in, serviceURL.toString(), SOAConstants.CACHE_POLICY_SCHEMA); throwErrorOnNull(holder); Collection<ServiceOperationDesc> operationServiceDescs = serviceDesc.getAllOperations(); Map<String, ServiceOperationParamDesc> opReqTypeMap = createOpRequestTypeDesc(operationServiceDescs); m_desc = CachePolicyDesc.create(holder, opReqTypeMap); throwErrorOnNull(m_desc); m_status = STATUS.INIT_SUCCESS; } catch (ServiceException e) { m_status = STATUS.INIT_FAILED; throw e; } finally { if (in != null) try { in.close(); } catch (Exception e) { // Ignoring it } } } /** * Helper method * @param in * @throws ServiceException */ private void throwErrorOnNull(Object in) throws ServiceException { if (in == null) { m_status = STATUS.INIT_FAILED; throw new ServiceException(ErrorDataFactory.createErrorData( ErrorConstants.SVC_CACHE_POLICY_INIT_FAILED, ErrorConstants.ERRORDOMAIN)); } } /** * Utility method to create the operation name -> request type mapping based on the * service operation desc information * @param operationServiceDescs : service operation descs * @return Map of operation name and operation request type */ private Map<String, ServiceOperationParamDesc> createOpRequestTypeDesc( Collection<ServiceOperationDesc> operationServiceDescs) { Map<String, ServiceOperationParamDesc> opReqTypeMap = new HashMap<String, ServiceOperationParamDesc>(); for(ServiceOperationDesc opDesc: operationServiceDescs) { opReqTypeMap.put(opDesc.getName(), opDesc.getRequestType()); } return opReqTypeMap; } /** * * Fetch the CachePolicy from the server, it is marked as protected for testability. * * @param serviceId Service Id * @param serviceURL Servicew end point. * * @return A InputStream to read the CachePolicy. * @throws ServiceException Exception when initialization fails. */ protected InputStream fetchCachePolicy(ClientServiceId serviceId, URL serviceURL) throws ServiceException { Preconditions.checkNotNull(serviceId); Preconditions.checkNotNull(serviceURL); Service service = ServiceFactory.create(serviceId.getAdminName(), serviceId.getEnvName(), serviceId.getClientName(), serviceURL); List<Object> outParams = new ArrayList<Object>(); service.invoke(SOAConstants.OP_GET_CACHE_POLICY, null, outParams); String cachePolicyStr = outParams.size() > 0 ? (String)outParams.get(0) : null; throwErrorOnNull(cachePolicyStr); InputStream in = convertToInputStream(cachePolicyStr); return in; } private InputStream convertToInputStream(String cachePolicyStr) { ByteArrayInputStream stream = new ByteArrayInputStream(cachePolicyStr.getBytes()); return stream; } /* * @see CacheProvider#isCacheEnabled() * */ @Override public final boolean isCacheEnabled() { /* ignore */ return m_status == STATUS.INIT_SUCCESS; } }