blob: 3184865f67dc8b7a71a82b08962587d58048427b [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF 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.apache.polygene.cache.memcache;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import net.spy.memcached.AddrUtil;
import net.spy.memcached.ConnectionFactoryBuilder;
import net.spy.memcached.ConnectionFactoryBuilder.Protocol;
import net.spy.memcached.MemcachedClient;
import net.spy.memcached.auth.AuthDescriptor;
import net.spy.memcached.auth.PlainCallbackHandler;
import org.apache.polygene.api.configuration.Configuration;
import org.apache.polygene.api.injection.scope.This;
import org.apache.polygene.spi.cache.Cache;
/**
* Memcache CachePool Mixin.
*/
public class MemcachePoolMixin
implements MemcachePoolService
{
private final Map<String, MemcacheImpl<?>> caches = new HashMap<>();
@This
private Configuration<MemcacheConfiguration> configuration;
private MemcachedClient client;
private int expiration;
@Override
public void activateService()
throws Exception
{
MemcacheConfiguration config = configuration.get();
expiration = ( config.expiration().get() == null )
? 3600
: config.expiration().get();
String addresses = ( config.addresses().get() == null )
? "localhost:11211"
: config.addresses().get();
Protocol protocol = ( config.protocol().get() == null )
? Protocol.TEXT
: Protocol.valueOf( config.protocol().get().toUpperCase() );
String username = config.username().get();
String password = config.password().get();
String authMech = config.authMechanism().get() == null
? "PLAIN"
: config.authMechanism().get();
ConnectionFactoryBuilder builder = new ConnectionFactoryBuilder();
builder.setProtocol( protocol );
if( username != null && !username.isEmpty() )
{
String[] authType = { authMech };
AuthDescriptor to = new AuthDescriptor( authType, new PlainCallbackHandler( username, password ) );
builder.setAuthDescriptor( to );
}
client = new MemcachedClient( builder.build(), AddrUtil.getAddresses( addresses ) );
}
@Override
public void passivateService()
throws Exception
{
if( client != null )
{
client.shutdown();
}
}
@Override
@SuppressWarnings( "unchecked" )
public <T> Cache<T> fetchCache( String cacheId, Class<T> valueType )
{
Objects.requireNonNull( cacheId, "cacheId" );
if( cacheId.isEmpty() )
{
throw new IllegalArgumentException( "cacheId was empty string" );
}
synchronized( caches )
{
MemcacheImpl<?> cache = caches.computeIfAbsent( cacheId, identity -> new MemcacheImpl<>( client, identity, valueType, expiration ) );
cache.incRefCount();
return (Cache<T>) cache;
}
}
@Override
public void returnCache( Cache<?> cache )
{
MemcacheImpl<?> memcache = (MemcacheImpl<?>) cache;
memcache.decRefCount();
synchronized( caches )
{
if( memcache.isNotUsed() )
{
caches.remove( memcache.cacheId() );
}
}
}
}