    001// Copyright 2013 The Apache Software Foundation
    002//
    003// Licensed under the Apache License, Version 2.0 (the "License");
    004// you may not use this file except in compliance with the License.
    005// You may obtain a copy of the License at
    006//
    007// http://www.apache.org/licenses/LICENSE-2.0
    008//
    009// Unless required by applicable law or agreed to in writing, software
    010// distributed under the License is distributed on an "AS IS" BASIS,
    011// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    012// See the License for the specific language governing permissions and
    013// limitations under the License.
    014
    015package org.apache.tapestry5.mongodb.modules;
    016
    017import com.mongodb.ReadPreference;
    018import com.mongodb.WriteConcern;
    019import org.apache.tapestry5.internal.mongodb.MongoDBImpl;
    020import org.apache.tapestry5.internal.mongodb.MongoDBSourceImpl;
    021import org.apache.tapestry5.ioc.Configuration;
    022import org.apache.tapestry5.ioc.MappedConfiguration;
    023import org.apache.tapestry5.ioc.ScopeConstants;
    024import org.apache.tapestry5.ioc.ServiceBinder;
    025import org.apache.tapestry5.ioc.annotations.Scope;
    026import org.apache.tapestry5.ioc.annotations.Symbol;
    027import org.apache.tapestry5.ioc.services.Coercion;
    028import org.apache.tapestry5.ioc.services.CoercionTuple;
    029import org.apache.tapestry5.ioc.services.PerthreadManager;
    030import org.apache.tapestry5.mongodb.MongoDB;
    031import org.apache.tapestry5.mongodb.MongoDBSource;
    032import org.apache.tapestry5.mongodb.MongoDBSymbols;
    033import org.slf4j.Logger;
    034
    035/**
    036 * Defines services which are responsible for MongoDB initializations and connections.
    037 */
    038public class MongodbModule
    039{
    040    public static void bind(ServiceBinder binder)
    041    {
    042        binder.bind(MongoDBSource.class, MongoDBSourceImpl.class);
    043    }
    044
    045    public static void contributeFactoryDefaults(MappedConfiguration<String, String> configuration)
    046    {
    047        configuration.add(MongoDBSymbols.CONNECTIONS_PER_HOSTS, "10");
    048        configuration.add(MongoDBSymbols.WRITE_CONCERN, "ACKNOWLEDGED");
    049        configuration.add(MongoDBSymbols.READ_PREFERENCE, "PRIMARY");
    050        configuration.add(MongoDBSymbols.CONSISTENT_REQUEST, "false");
    051
    052                // Authentication (Mongo in secure mode)
    053
    054                configuration.add(MongoDBSymbols.SECURE_MODE, "false");
    055                configuration.add(MongoDBSymbols.DB_USERNAME, "");
    056                configuration.add(MongoDBSymbols.DB_PASSWORD, "");
    057    }
    058
    059    @Scope(ScopeConstants.PERTHREAD)
    060    public static MongoDB buildMongoDB(Logger logger, final MongoDBSource mongoDBSource,
    061                     PerthreadManager perthreadManager,
    062                     @Symbol(MongoDBSymbols.DEFAULT_DB_NAME) String defaultDbName,
    063                     @Symbol(MongoDBSymbols.CONSISTENT_REQUEST) boolean consistentRequest,
    064                                         @Symbol(MongoDBSymbols.SECURE_MODE) boolean secureMode,
    065                                         @Symbol(MongoDBSymbols.DB_USERNAME) String dbUsername,
    066                                         @Symbol(MongoDBSymbols.DB_PASSWORD) String dbPassword)
    067    {
    068        final MongoDBImpl mongoDB = new MongoDBImpl(logger, mongoDBSource,
    069                defaultDbName, consistentRequest, secureMode, dbUsername, dbPassword);
    070
    071                perthreadManager.addThreadCleanupListener(mongoDB);
    072
    073        return mongoDB;
    074    }
    075
    076    /**
    077     * Contribute coercions for {@link WriteConcern} and {@link ReadPreference} to have them from
    078     * {@link org.apache.tapestry5.ioc.annotations.Symbol}
    079     *
    080     * @param configuration lets help the {@link org.apache.tapestry5.ioc.services.TypeCoercer} service
    081     */
    082    public static void contributeTypeCoercer(Configuration<CoercionTuple> configuration)
    083    {
    084        configuration.add(new CoercionTuple(String.class, WriteConcern.class,
    085                new Coercion<String, WriteConcern>() {
    086                    public WriteConcern coerce(String input)
    087                    {
    088                        if (input.equalsIgnoreCase("FSYNC_SAFE"))
    089                        {
    090                            return WriteConcern.FSYNC_SAFE;
    091                        }
    092                        else if (input.equalsIgnoreCase("JOURNAL_SAFE"))
    093                        {
    094                            return WriteConcern.JOURNAL_SAFE;
    095                        }
    096                        else if (input.equalsIgnoreCase("MAJORITY"))
    097                        {
    098                            return WriteConcern.MAJORITY;
    099                        }
    100                        else if (input.equalsIgnoreCase("NONE"))
    101                        {
    102                            return WriteConcern.NONE;
    103                        }
    104                        else if (input.equalsIgnoreCase("REPLICAS_SAFE"))
    105                        {
    106                            return WriteConcern.REPLICAS_SAFE;
    107                        }
    108                        else if (input.equalsIgnoreCase("SAFE"))
    109                        {
    110                            return WriteConcern.SAFE;
    111                        }
    112                                                else if (input.equalsIgnoreCase("NORMAL"))
    113                                                {
    114                                                        return WriteConcern.NORMAL;
    115                                                }
    116                        else // WriteConcern.ACKNOWLEDGED IS OUR DEFAULT
    117                        {
    118                            return WriteConcern.ACKNOWLEDGED;
    119                        }
    120                    }
    121                }
    122        ));
    123
    124        configuration.add(new CoercionTuple(String.class, ReadPreference.class, new Coercion<String, ReadPreference>() {
    125            public ReadPreference coerce(String input)
    126            {
    127                if (input.equalsIgnoreCase("SECONDARY"))
    128                {
    129                    return ReadPreference.secondary();
    130                }
    131                else // PRIMARY IS OUR DEFAULT
    132                {
    133                    return ReadPreference.primary();
    134                }
    135            }
    136        }));
    137    }
    138}