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}