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}