All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.marvelution.jira.plugins.sonar.services.servers.CacheAwareSonarDelegatingConnector Maven / Gradle / Ivy

/*
 * Licensed to Marvelution under one or more contributor license
 * agreements.  See the NOTICE file distributed with this work
 * for additional information regarding copyright ownership.
 * Marvelution 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 com.marvelution.jira.plugins.sonar.services.servers;

import static com.google.common.base.Preconditions.checkNotNull;

import net.java.ao.DBParam;

import org.apache.log4j.Logger;
import org.sonar.wsclient.connectors.Connector;
import org.sonar.wsclient.services.CreateQuery;
import org.sonar.wsclient.services.DeleteQuery;
import org.sonar.wsclient.services.Query;
import org.sonar.wsclient.services.UpdateQuery;

import com.atlassian.activeobjects.external.ActiveObjects;
import com.atlassian.sal.api.transaction.TransactionCallback;
import com.marvelution.jira.plugins.sonar.services.servers.cache.ServerCache;

/**
 * Cache Aware implementation of the {@link Connector} base class.
 * 
 * @author Mark Rekveld
 *
 * @since 3.0.0
 */
public class CacheAwareSonarDelegatingConnector extends Connector {

	private static final Logger LOGGER = Logger.getLogger(CacheAwareSonarDelegatingConnector.class);
	private static final long CACHE_TIMEOUT = 10 * 60 * 1000;

	private final Connector delegator;
	private final ActiveObjects objects;
	private final SonarServer server;

	/**
	 * Constructor
	 *
	 * @param delegator
	 */
	public CacheAwareSonarDelegatingConnector(ActiveObjects objects, SonarServer server, Connector delegator) {
		this.delegator = checkNotNull(delegator, "delegator");
		this.objects = checkNotNull(objects, "objects");
		this.server = checkNotNull(server, "server");
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public String execute(final Query query) {
		return objects.executeInTransaction(new TransactionCallback() {

			/**
			 * {@inheritDoc}
			 */
			@Override
			public String doInTransaction() {
				ServerCache[] caches = objects.find(ServerCache.class, net.java.ao.Query.select()
					.where("SERVER_ID = ? AND QUERY = ?", server.getID(), query.getUrl()).limit(1));
				if (caches == null || caches.length == 0) {
					return updateCache(objects.create(ServerCache.class, new DBParam("SERVER_ID", server.getID()), new DBParam("QUERY", query.getUrl())), query);
				} else if (caches[0].getLastUpdate() >= System.currentTimeMillis() - CACHE_TIMEOUT) {
					return updateCache(caches[0], query);
				} else {
					LOGGER.debug("Returning cached response for query: " + query.getUrl());
					return caches[0].getResponse();
				}
			}

			/**
			 * Method to update the given {@link ServerCache}
			 * 
			 * @param cache the {@link ServerCache} to update
			 * @param query the {@link Query} to use to update the cache
			 * @return the query response
			 */
			private String updateCache(ServerCache cache, Query query) {
				String response = delegator.execute(query);
				cache.setLastUpdate(System.currentTimeMillis());
				cache.setResponse(response);
				cache.save();
				LOGGER.debug("Updated cached response for query: " + query.getUrl());
				return response;
			}

		});
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public String execute(CreateQuery createQuery) {
		// CreateQuery executions are not cached, so just forward to the delegator
		return delegator.execute(createQuery);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public String execute(DeleteQuery deleteQuery) {
		// DeleteQuery executions are not cached, so just forward to the delegator
		return delegator.execute(deleteQuery);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public String execute(UpdateQuery updateQuery) {
		// UpdateQuery executions are not cached, so just forward to the delegator
		return delegator.execute(updateQuery);
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy