View Javadoc

1   /**
2    * Licensed to jclouds, Inc. (jclouds) under one or more
3    * contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  jclouds licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.jclouds.compute.predicates;
20  
21  import java.util.concurrent.TimeUnit;
22  
23  import javax.annotation.Resource;
24  import javax.inject.Inject;
25  import javax.inject.Named;
26  
27  import org.jclouds.compute.reference.ComputeServiceConstants;
28  import org.jclouds.compute.reference.ComputeServiceConstants.Timeouts;
29  import org.jclouds.logging.Logger;
30  import org.jclouds.net.IPSocket;
31  import org.jclouds.predicates.RetryablePredicate;
32  import org.jclouds.predicates.SocketOpen;
33  
34  import com.google.common.base.Predicate;
35  
36  /**
37   * 
38   * 
39   * Not singleton as seconds are mutable
40   * 
41   * @author Adrian Cole
42   * 
43   */
44  public class RetryIfSocketNotYetOpen implements Predicate<IPSocket> {
45     @Resource
46     @Named(ComputeServiceConstants.COMPUTE_LOGGER)
47     private Logger logger = Logger.NULL;
48     private final SocketOpen socketTester;
49     private long timeoutValue;
50     private TimeUnit timeoutUnits;
51  
52  
53     public RetryIfSocketNotYetOpen(SocketOpen socketTester, Logger logger, long timeoutValue, TimeUnit timeoutUnits) {
54        this.socketTester = socketTester;
55        this.logger = logger;
56        this.timeoutValue = timeoutValue;
57        this.timeoutUnits = timeoutUnits;
58     }
59     
60     public RetryIfSocketNotYetOpen(SocketOpen socketTester, Logger logger) {
61        this(socketTester, logger, 0, TimeUnit.MILLISECONDS);
62     }
63  
64     @Inject
65     public RetryIfSocketNotYetOpen(SocketOpen socketTester, Timeouts timeouts) {
66         this(socketTester, Logger.NULL, timeouts.portOpen, TimeUnit.MILLISECONDS);
67     }
68     
69     /** @deprecated in favor of specifying explicit time units */
70     @Deprecated
71     public RetryIfSocketNotYetOpen(SocketOpen socketTester, Logger logger, long seconds) {
72        this(socketTester, logger, seconds, TimeUnit.SECONDS);
73     }
74  
75     public RetryIfSocketNotYetOpen milliseconds(long milliseconds) {
76         this.timeoutValue = milliseconds;
77         this.timeoutUnits = TimeUnit.MILLISECONDS;
78         return this;
79     }
80     
81     public RetryIfSocketNotYetOpen seconds(long seconds) {
82        this.timeoutValue = seconds;
83        this.timeoutUnits = TimeUnit.SECONDS;
84        return this;
85     }
86  
87     @Override
88     public String toString() {
89        return "retryIfSocketNotYetOpen(" + timeoutValue + " "+ timeoutUnits + ")";
90     }
91  
92     @Override
93     public boolean apply(IPSocket socket) {
94        logger.debug(">> blocking on socket %s for %d %s", socket, timeoutValue, timeoutUnits);
95        // Specify a retry period of 1s, expressed in the same time units.
96        long period = timeoutUnits.convert(1, TimeUnit.SECONDS);
97        RetryablePredicate<IPSocket> tester = new RetryablePredicate<IPSocket>(socketTester, timeoutValue, period, timeoutUnits);
98        boolean passed = tester.apply(socket);
99        if (passed)
100          logger.debug("<< socket %s opened", socket);
101       else
102          logger.warn("<< socket %s didn't open after %d %s", socket, timeoutValue, timeoutUnits);
103       return passed;
104    }
105 }