Project

General

Profile

Download (8.43 KB) Statistics
| Branch: | Tag: | Revision:
1
package eu.etaxonomy.cdm.server.instance;
2

    
3
import java.lang.reflect.InvocationTargetException;
4
import java.sql.Connection;
5
import java.sql.SQLException;
6
import java.util.ArrayList;
7
import java.util.List;
8

    
9
import javax.naming.InitialContext;
10
import javax.naming.NamingException;
11
import javax.sql.DataSource;
12

    
13
import org.apache.log4j.Logger;
14
import org.eclipse.jetty.plus.jndi.Resource;
15
import org.eclipse.jetty.server.handler.ContextHandler.Context;
16
import org.eclipse.jetty.util.component.LifeCycle;
17
import org.eclipse.jetty.util.component.LifeCycle.Listener;
18
import org.eclipse.jetty.webapp.WebAppContext;
19

    
20
import com.mchange.v2.c3p0.DataSources;
21

    
22

    
23
public class CdmInstance implements Listener {
24

    
25
    private static final Logger logger = Logger.getLogger(CdmInstance.class);
26

    
27
    private WebAppContext webAppContext = null;
28

    
29
    private Configuration configuration;
30

    
31
    private List<String> problems;
32
    private Status status = Status.uninitialized;
33

    
34
    private Resource jndiDataSource;
35

    
36
    public CdmInstance(Configuration configuration) {
37
        this.configuration = configuration;
38
    }
39

    
40
    public List<String> getProblems() {
41
        if (problems == null) {
42
            problems = new ArrayList<String>();
43
        }
44
        return problems;
45
    }
46

    
47
    public void setProblems(List<String> problems) {
48
        this.problems = problems;
49
    }
50

    
51
    public boolean onError() {
52
        return status.equals(Status.error);
53
    }
54

    
55
    /**
56
     * @param status
57
     *            the status to set
58
     */
59
    public void setStatus(Status status) {
60
        this.status = status;
61
    }
62

    
63
    /**
64
     * @return the status
65
     */
66
    public Status getStatus() {
67
        return status;
68
    }
69

    
70
    /**
71
     * @return true if status is not {@link Status#disabled}
72
     */
73
    public boolean isEnabled() {
74
        return !status.equals(Status.disabled);
75
    }
76

    
77
    /**
78
     * @return the configuration
79
     */
80
    public Configuration getConfiguration() {
81
        return configuration;
82
    }
83

    
84
    /**
85
     * @return the configuration
86
     */
87
    public void setConfiguration(Configuration configuration) {
88
        this.configuration = configuration;
89
    }
90

    
91
    /**
92
     * @return the webAppContext
93
     */
94
    public WebAppContext getWebAppContext() {
95
        return webAppContext;
96
    }
97

    
98
    /**
99
     * @return the webAppContext
100
     */
101
    public void setWebAppContext(WebAppContext webAppContext) {
102
        this.webAppContext = webAppContext;
103
    }
104

    
105
    public String getName() {
106
        return getConfiguration().getInstanceName();
107
    }
108

    
109
    /**
110
     * @param <T>
111
     * @param webAppContext
112
     * @param attributeName
113
     * @param type
114
     * @return
115
     */
116
    @SuppressWarnings("unchecked")
117
    private <T> T getServletContextAttribute(WebAppContext webAppContext, String attributeName, Class<T> type) {
118

    
119
        Context servletContext = webAppContext.getServletContext();
120
        Object value = servletContext.getAttribute(attributeName);
121
        if (value != null && type.isAssignableFrom(value.getClass())) {
122

    
123
        }
124
        return (T) value;
125
    }
126

    
127
    @Override
128
    public void lifeCycleStopping(LifeCycle event) {
129
        logger.info("lifeCycleStopping");
130
        if(!getStatus().equals(Status.removed)){
131
            // never override Status.removed !!!
132
            setStatus(Status.stopping);
133
        }
134
    }
135

    
136
    @Override
137
    public void lifeCycleStopped(LifeCycle event) {
138
        logger.info("lifeCycleStopped");
139
        if(!getStatus().equals(Status.removed)){
140
            // never override Status.removed !!!
141
            setStatus(Status.stopped);
142
        }
143

    
144
    }
145

    
146
    @Override
147
    public void lifeCycleStarting(LifeCycle event) {
148
        logger.info("lifeCycleStarting");
149
        setStatus(Status.starting);
150
        setProblems(null);
151
    }
152

    
153
    @SuppressWarnings("unchecked")
154
    @Override
155
    public void lifeCycleStarted(LifeCycle event) {
156
        logger.info("lifeCycleStarted");
157

    
158
        List<String> messages = getServletContextAttribute(webAppContext, SharedAttributes.ATTRIBUTE_ERROR_MESSAGES, List.class);
159
        String dataSourceName = getServletContextAttribute(webAppContext, SharedAttributes.ATTRIBUTE_DATASOURCE_NAME, String.class);
160

    
161
        if (messages != null && dataSourceName != null) {
162
            // Problems with instance
163
            Status errorStatus = Status.error;
164
            for(String message : messages){
165
                if(message.startsWith("Incompatible version")){
166
                    errorStatus = Status.incompatible_version;
167
                    break;
168
                }
169
            }
170
            setStatus(errorStatus);
171

    
172
            getProblems().addAll(messages);
173

    
174
            try {
175
                logger.warn("Stopping context '" + dataSourceName + "' due to errors reported in ServletContext");
176
                webAppContext.stop();
177
                setStatus(errorStatus);
178
            } catch (Exception e) {
179
                logger.error(e);
180
            }
181
        } else {
182
            // Instance is OK
183
            setStatus(Status.started);
184
        }
185
    }
186

    
187
    @Override
188
    public void lifeCycleFailure(LifeCycle event, Throwable cause) {
189
        logger.error("lifeCycleFailure");
190
        if(!getStatus().equals(Status.removed)){
191
            // never override Status.removed !!!
192
            setStatus(Status.error);
193
        }
194
        getProblems().add(cause.getMessage());
195
    }
196

    
197
    public void releaseWebAppContext() {
198
        webAppContext = null;
199
    }
200

    
201
    public boolean bindJndiDataSource() {
202
        try {
203
            Class<DataSource> dsCass = (Class<DataSource>) Thread.currentThread().getContextClassLoader().loadClass("com.mchange.v2.c3p0.ComboPooledDataSource");
204
            DataSource datasource = dsCass.newInstance();
205
            dsCass.getMethod("setDriverClass", new Class[] {String.class}).invoke(datasource, new Object[] {configuration.getDriverClass()});
206
            dsCass.getMethod("setJdbcUrl", new Class[] {String.class}).invoke(datasource, new Object[] {configuration.getDataSourceUrl()});
207
            dsCass.getMethod("setUser", new Class[] {String.class}).invoke(datasource, new Object[] {configuration.getUsername()});
208
            dsCass.getMethod("setPassword", new Class[] {String.class}).invoke(datasource, new Object[] {configuration.getPassword()});
209

    
210
            Connection connection = null;
211
            String sqlerror = null;
212
            try {
213
                connection = datasource.getConnection();
214
                connection.close();
215
            } catch (SQLException e) {
216
                sqlerror = e.getMessage() + "["+ e.getSQLState() + "]";
217
                getProblems().add(sqlerror);
218
                setStatus(Status.error);
219
                if(connection !=  null){
220
                    try {connection.close();} catch (SQLException e1) { /* IGNORE */ }
221
                }
222
                logger.error(configuration.toString() + " has problem : "+ sqlerror );
223
            }
224

    
225
            if(!onError()){
226
                logger.info("binding jndi datasource at " + configuration.getJdbcJndiName() + " with " + configuration.getUsername() +"@"+ configuration.getDataSourceUrl());
227
                jndiDataSource = new Resource(configuration.getJdbcJndiName(), datasource);
228
                return true;
229
            }
230

    
231
        } catch (IllegalArgumentException e) {
232
            logger.error(e);
233
            e.printStackTrace();
234
        } catch (SecurityException e) {
235
            logger.error(e);
236
        } catch (ClassNotFoundException e) {
237
            logger.error(e);
238
        } catch (InstantiationException e) {
239
            logger.error(e);
240
        } catch (IllegalAccessException e) {
241
            logger.error(e);
242
        } catch (InvocationTargetException e) {
243
            logger.error(e);
244
        } catch (NoSuchMethodException e) {
245
            logger.error(e);
246
        } catch (NamingException e) {
247
            logger.error(e);
248
        }
249
        return false;
250
    }
251

    
252
    public void unbindJndiDataSource() {
253

    
254
        if(jndiDataSource == null) {
255
            return; // nothing to to
256
        }
257

    
258
        try {
259
            InitialContext ic = new InitialContext();
260
            Object o = ic.lookup(jndiDataSource.getJndiNameInScope());
261
            if(o instanceof DataSource) {
262
                DataSources.destroy((DataSource) o);
263
                logger.info("datasource for " + jndiDataSource.getJndiNameInScope() + " destroyed");
264
            }
265
        } catch (NamingException e) {
266
            logger.error(e);
267
        } catch (SQLException e) {
268
            logger.error(e);
269
        }
270
        if(jndiDataSource != null){
271
            jndiDataSource.release();
272
            jndiDataSource = null;
273
        }
274
    }
275

    
276

    
277

    
278
}
(1-1/7)