    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;
    019
    020import org.apache.tapestry5.commons.Configuration;
    021import org.apache.tapestry5.commons.MappedConfiguration;
    022import org.apache.tapestry5.commons.services.Coercion;
    023import org.apache.tapestry5.commons.services.CoercionTuple;
    024import org.apache.tapestry5.internal.mongodb.MongoDBImpl;
    025import org.apache.tapestry5.internal.mongodb.MongoDBSourceImpl;
    026import org.apache.tapestry5.ioc.ScopeConstants;
    027import org.apache.tapestry5.ioc.ServiceBinder;
    028import org.apache.tapestry5.ioc.annotations.Scope;
    029import org.apache.tapestry5.ioc.annotations.Symbol;
    030import org.apache.tapestry5.ioc.services.PerthreadManager;
    031import org.apache.tapestry5.mongodb.MongoDB;
    032import org.apache.tapestry5.mongodb.MongoDBSource;
    033import org.apache.tapestry5.mongodb.MongoDBSymbols;
    034import org.slf4j.Logger;
    035
    036/**
    037 * Defines services which are responsible for MongoDB initializations and connections.
    038 */
    039public class MongodbModule
    040{
    041    public static void bind(ServiceBinder binder)
    042    {
    043        binder.bind(MongoDBSource.class, MongoDBSourceImpl.class);
    044    }
    045
    046    public static void contributeFactoryDefaults(MappedConfiguration<String, String> configuration)
    047    {
    048        configuration.add(MongoDBSymbols.CONNECTIONS_PER_HOSTS, "10");
    049        configuration.add(MongoDBSymbols.WRITE_CONCERN, "ACKNOWLEDGED");
    050        configuration.add(MongoDBSymbols.READ_PREFERENCE, "PRIMARY");
    051        configuration.add(MongoDBSymbols.CONSISTENT_REQUEST, "false");
    052
    053                // Authentication (Mongo in secure mode)
    054
    055                configuration.add(MongoDBSymbols.SECURE_MODE, "false");
    056                configuration.add(MongoDBSymbols.DB_USERNAME, "");
    057                configuration.add(MongoDBSymbols.DB_PASSWORD, "");
    058    }
    059
    060    @Scope(ScopeConstants.PERTHREAD)
    061    public static MongoDB buildMongoDB(Logger logger, final MongoDBSource mongoDBSource,
    062                     PerthreadManager perthreadManager,
    063                     @Symbol(MongoDBSymbols.DEFAULT_DB_NAME) String defaultDbName,
    064                     @Symbol(MongoDBSymbols.CONSISTENT_REQUEST) boolean consistentRequest,
    065                                         @Symbol(MongoDBSymbols.SECURE_MODE) boolean secureMode,
    066                                         @Symbol(MongoDBSymbols.DB_USERNAME) String dbUsername,
    067                                         @Symbol(MongoDBSymbols.DB_PASSWORD) String dbPassword)
    068    {
    069        final MongoDBImpl mongoDB = new MongoDBImpl(logger, mongoDBSource,
    070                defaultDbName, consistentRequest, secureMode, dbUsername, dbPassword);
    071
    072                perthreadManager.addThreadCleanupListener(mongoDB);
    073
    074        return mongoDB;
    075    }
    076
    077    /**
    078     * Contribute coercions for {@link WriteConcern} and {@link ReadPreference} to have them from
    079     * {@link org.apache.tapestry5.ioc.annotations.Symbol}
    080     *
    081     * @param configuration lets help the {@link org.apache.tapestry5.commons.services.TypeCoercer} service
    082     */
    083    public static void contributeTypeCoercer(MappedConfiguration<CoercionTuple.Key, CoercionTuple> configuration)
    084    {
    085        CoercionTuple stringToWriteConcern = new CoercionTuple(String.class, WriteConcern.class,
    086                new Coercion<String, WriteConcern>() {
    087                    public WriteConcern coerce(String input)
    088                    {
    089                        if (input.equalsIgnoreCase("FSYNC_SAFE"))
    090                        {
    091                            return WriteConcern.FSYNC_SAFE;
    092                        }
    093                        else if (input.equalsIgnoreCase("JOURNAL_SAFE"))
    094                        {
    095                            return WriteConcern.JOURNAL_SAFE;
    096                        }
    097                        else if (input.equalsIgnoreCase("MAJORITY"))
    098                        {
    099                            return WriteConcern.MAJORITY;
    100                        }
    101                        else if (input.equalsIgnoreCase("NONE"))
    102                        {
    103                            return WriteConcern.NONE;
    104                        }
    105                        else if (input.equalsIgnoreCase("REPLICAS_SAFE"))
    106                        {
    107                            return WriteConcern.REPLICAS_SAFE;
    108                        }
    109                        else if (input.equalsIgnoreCase("SAFE"))
    110                        {
    111                            return WriteConcern.SAFE;
    112                        }
    113                                                else if (input.equalsIgnoreCase("NORMAL"))
    114                                                {
    115                                                        return WriteConcern.NORMAL;
    116                                                }
    117                        else // WriteConcern.ACKNOWLEDGED IS OUR DEFAULT
    118                        {
    119                            return WriteConcern.ACKNOWLEDGED;
    120                        }
    121                    }
    122                }
    123        );
    124        configuration.add(stringToWriteConcern.getKey(), stringToWriteConcern);
    125
    126        CoercionTuple stringToReadPreference = new CoercionTuple(String.class, ReadPreference.class, new Coercion<String, ReadPreference>() {
    127            public ReadPreference coerce(String input)
    128            {
    129                if (input.equalsIgnoreCase("SECONDARY"))
    130                {
    131                    return ReadPreference.secondary();
    132                }
    133                else // PRIMARY IS OUR DEFAULT
    134                {
    135                    return ReadPreference.primary();
    136                }
    137            }
    138        });
    139        configuration.add(stringToReadPreference.getKey(), stringToReadPreference);
    140    }
    141}