/*
*  Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
*  WSO2 Inc. licenses this file to you 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.wso2.carbon.apimgt.impl.clients;

import org.apache.axis2.AxisFault;
import org.apache.axis2.client.Options;
import org.apache.axis2.client.ServiceClient;
import org.apache.axis2.client.Stub;
import org.apache.axis2.context.ConfigurationContext;
import org.apache.axis2.context.ConfigurationContextFactory;
import org.apache.axis2.context.ServiceContext;
import org.apache.axis2.transport.http.HTTPConstants;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.apimgt.api.APIManagementException;
import org.wso2.carbon.apimgt.impl.APIConstants;
import org.wso2.carbon.apimgt.impl.APIManagerConfiguration;
import org.wso2.carbon.apimgt.impl.dto.Environment;
import org.wso2.carbon.apimgt.impl.internal.ServiceReferenceHolder;
import org.wso2.carbon.apimgt.tier.cache.stub.TierCacheServiceStub;
import org.wso2.carbon.authenticator.stub.AuthenticationAdminStub;
import org.wso2.carbon.authenticator.stub.LoginAuthenticationExceptionException;
import org.wso2.carbon.context.CarbonContext;

import java.net.MalformedURLException;
import java.net.URL;
import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class TierCacheInvalidationClient {
    private static final Log log = LogFactory.getLog(TierCacheInvalidationClient.class);
    private static final int TIMEOUT_IN_MILLIS = 15 * 60 * 1000;

    Map<String, Environment> environments;
    
    String storeServerURL;
    
    String storeUserName;
    
    String storePassword;
    
    String publisherServerURL;
    
    String publisherUserName;
    
    String publisherPassword;

    public TierCacheInvalidationClient() throws APIManagementException {
        APIManagerConfiguration config =
                                         ServiceReferenceHolder.getInstance().getAPIManagerConfigurationService()
                                                               .getAPIManagerConfiguration();
        environments = config.getApiGatewayEnvironments();
        storeServerURL = config.getFirstProperty(APIConstants.API_STORE_SERVER_URL);
        storeUserName = config.getFirstProperty(APIConstants.API_STORE_USERNAME);
        storePassword = config.getFirstProperty(APIConstants.API_STORE_PASSWORD);

        publisherServerURL = config.getFirstProperty(APIConstants.API_PUBLISHER_SERVER_URL);
        publisherUserName = config.getFirstProperty(APIConstants.API_PUBLISHER_USERNAME);
        publisherPassword = config.getFirstProperty(APIConstants.API_PUBLISHER_PASSWORD);
    }

    public void clearCaches(String tenantDomain) {
        String cookie;

        // Clear Store Cache
        try {
            cookie = login(storeServerURL, storeUserName, storePassword);
            clearCache(tenantDomain, storeServerURL, cookie);
        } catch (AxisFault axisFault) {
            log.error("Error while initializing the OAuth admin service stub in Store for tenant : " + tenantDomain,
                      axisFault);
        } catch (RemoteException e) {
            log.error("Error while invalidating the tier cache in Store for tenant : " + tenantDomain, e);
        }

        // Clear Publisher Cache
        try {
            cookie = login(storeServerURL, storeUserName, storePassword);
            clearCache(tenantDomain, storeServerURL, cookie);
        } catch (AxisFault axisFault) {
            log.error("Error while initializing the OAuth admin service stub in Publisher for tenant : " + tenantDomain,
                      axisFault);
        } catch (RemoteException e) {
            log.error("Error while invalidating the tier cache in Publisher for tenant : " + tenantDomain, e);
        }

        // Clear Gateway Caches
        if (environments == null || environments.isEmpty()) {
            if (log.isDebugEnabled()) {
                log.debug("Unable to find the list of gateway environments");
            }
            return;
        }
        String gatewayServerURL;
        for (Map.Entry<String, Environment> entry : environments.entrySet()) {
            Environment environment = entry.getValue();
            gatewayServerURL = environment.getServerURL();
            try {
                cookie = login(gatewayServerURL, environment.getUserName(), environment.getPassword());
                clearCache(tenantDomain, gatewayServerURL, cookie);
            } catch (AxisFault axisFault) {
                log.error("Error while initializing the OAuth admin service stub for gateway environment : " +
                          entry.getValue().getName() + " for tenant : " + tenantDomain, axisFault);
                continue;
            } catch (RemoteException e) {
                log.error("Error while invalidating the tier cache for gateway environment : " +
                          entry.getValue().getName() + " for tenant : " + tenantDomain, e);
            }
        }
    }

    public void clearCache(String tenantDomain, String serverURL, String cookie) throws AxisFault, RemoteException {
        TierCacheServiceStub tierCacheServiceStub;

        ConfigurationContext ctx = ConfigurationContextFactory.createConfigurationContextFromFileSystem(null, null);
        tierCacheServiceStub = new TierCacheServiceStub(ctx, serverURL + "TierCacheService");
        ServiceClient client = tierCacheServiceStub._getServiceClient();
        Options options = client.getOptions();
        options.setTimeOutInMilliSeconds(TIMEOUT_IN_MILLIS);
        options.setProperty(HTTPConstants.SO_TIMEOUT, TIMEOUT_IN_MILLIS);
        options.setProperty(HTTPConstants.CONNECTION_TIMEOUT, TIMEOUT_IN_MILLIS);
        options.setManageSession(true);
        options.setProperty(HTTPConstants.COOKIE_STRING, cookie);

        tierCacheServiceStub.invalidateCache(tenantDomain);
    }

    private String login(String serverURL, String userName, String password) throws AxisFault {
        if (serverURL == null || userName == null || password == null) {
            throw new AxisFault("Required admin configuration unspecified");
        }

        String host;
        try {
            host = new URL(serverURL).getHost();
        } catch (MalformedURLException e) {
            throw new AxisFault("Server URL is malformed", e);
        }

        AuthenticationAdminStub authAdminStub = new AuthenticationAdminStub(null, serverURL + "AuthenticationAdmin");
        ServiceClient client = authAdminStub._getServiceClient();
        Options options = client.getOptions();
        options.setManageSession(true);
        try {
            authAdminStub.login(userName, password, host);
            ServiceContext serviceContext = authAdminStub.
                    _getServiceClient().getLastOperationContext().getServiceContext();
            return (String) serviceContext.getProperty(HTTPConstants.COOKIE_STRING);
        } catch (RemoteException e) {
            throw new AxisFault("Error while contacting the authentication admin services", e);
        } catch (LoginAuthenticationExceptionException e) {
            throw new AxisFault("Error while authenticating ", e);
        }
    }

}

@@ -3829,33 +3829,32 @@
 ;%0A        %7D%0A
-%0A
         
 // Clear Pub
@@ -3845,1746 +3845,8 @@
     
-// Clear Publisher Cache%0A        try %7B%0A            cookie = login(storeServerURL, storeUserName, storePassword);%0A            clearCache(tenantDomain, storeServerURL, cookie);%0A        %7D catch (AxisFault axisFault) %7B%0A            log.error(%22Error while initializing the OAuth admin service stub in Publisher for tenant : %22 + tenantDomain,%0A                      axisFault);%0A        %7D catch (RemoteException e) %7B%0A            log.error(%22Error while invalidating the tier cache in Publisher for tenant : %22 + tenantDomain, e);%0A        %7D%0A%0A        // Clear Gateway Caches%0A        if (environments == null %7C%7C environments.isEmpty()) %7B%0A            if (log.isDebugEnabled()) %7B%0A                log.debug(%22Unable to find the list of gateway environments%22);%0A            %7D%0A            return;%0A        %7D%0A        String gatewayServerURL;%0A        for (Map.Entry%3CString, Environment%3E entry : environments.entrySet()) %7B%0A            Environment environment = entry.getValue();%0A            gatewayServerURL = environment.getServerURL();%0A            try %7B%0A                cookie = login(gatewayServerURL, environment.getUserName(), environment.getPassword());%0A                clearCache(tenantDomain, gatewayServerURL, cookie);%0A            %7D catch (AxisFault axisFault) %7B%0A                log.error(%22Error while initializing the OAuth admin service stub for gateway environment : %22 +%0A                          entry.getValue().getName() + %22 for tenant : %22 + tenantDomain, axisFault);%0A                continue;%0A            %7D catch (RemoteException e) %7B%0A                log.error(%22Error while invalidating the tier cache for gateway environment : %22 +%0A                          entry.getValue().getName() + %22 for tenant : %22 + tenantDomain, e);%0A            %7D%0A        %7D
 %0A   

Remove unused store, gateway tier cache invalidation