@Retryable не работает при вызове из метода - PullRequest
0 голосов
/ 26 февраля 2019

Ниже мой класс приложения.Поток подобен классу DEToken отсюда и DEToken, я вызываю RestConnection, где у меня есть метод @retryable.

@SpringBootApplication
@EnableRetry
public class SpringBootTrfficApplication implements CommandLineRunner {

    Enter code here

    @Autowired
    DEToken deToken;

    @Autowired
    SyncService syncService;
    public static void main(String[] args) {
        SpringApplication.run(SpringBootTrfficApplication.class, args);
    }

    @Override
    public void run(String... args) throws Exception {
        deToken.getToken();
    }
}

Класс DEToken: от getToken Я звоню RestConnect где у меня есть метод @Retrable:

@Service
public class DEToken {
    private Logger logger = LogManager.getLogger(getClass());

    @Autowired
    RestConnection restConnection;

    @Autowired
    private Environment env;

    public String accessToken;

    public void getToken() {
        System.out.println("hello from get token");
        //String getJsonPayload = "{\"Query\":{\"RegisterExtensionWithDE\":{\"pid\": \"\",\"providerInsName\":" +
        //env.getProperty("provider.ins") + "}}}";
        //String str = restConnection.restPost(
        //    env.getProperty("rest.de.url"), getJsonPayload);

        try {
            String getJsonPayload =
                "{\"Query\":{\"RegisterExtensionWithDE\":{\"pid\": \"\",\"providerInsName\":" +
                env.getProperty("provider.ins") + "}}}";
            StringBuffer tokenResult =
                restConnection.restPost(env.getProperty("rest.de.url"),
                                        getJsonPayload);
            System.out.println(tokenResult);
            JSONObject xmlJSONObj = XML.toJSONObject(tokenResult.toString());
            JSONObject registration = new JSONObject();
            if (xmlJSONObj.has("Registration")) {
                registration  = xmlJSONObj.getJSONObject("Registration");
                if (registration.has("accessToken")) {
                    accessToken = registration.get("accessToken").toString();
                }
                else
                    logger.info("no accessToken from DE");
            }
            else
                logger.info("no Registration object from DE");
        }
        catch (Exception e) {
            logger.error("Exception while fetching accesstoken from DE ");
            logger.error(e.getMessage());
        }
    }
}

Мой класс соединения REST, где у меня есть метод retryable:

@Service
public class RestConnection {

    private Logger logger = LogManager.getLogger(getClass());

    @Autowired
    private Environment env;

    public void setBaseUrl(String value, String ip) {
        //baseUrl = value;
        HttpsURLConnection.setDefaultHostnameVerifier(
            (hostname, session) -> hostname.equals(ip));
    }


    /*
     * REST post call
     */
    @Retryable(value = {IOException.class, ConnectException.class},
               maxAttempts = 4,
               backoff = @Backoff(5000))
    public StringBuffer restPost(String restUrl, String payload) {
        StringBuffer sb = new StringBuffer();
        HttpURLConnection conn = null;
        try {
            URL url = new URL(restUrl);
            String protocol = url.getProtocol();
            if (protocol.toLowerCase().equals("http")) {
                conn = (HttpURLConnection)url.openConnection();
            }
            else if (protocol.toLowerCase().equals("https")) {
                //setTrustedCert();
                conn = (HttpsURLConnection)url.openConnection();
            }
            else {
                logger.info("Protocol is neither HTTP nor HTTPS");
            }
            conn.setDoOutput(true);
            conn.setDoInput(true);
            conn.setRequestMethod("POST");
            conn.setRequestProperty("Content-Type", "application/json");
            conn.setRequestProperty("Accept", "application/json");
            conn.setRequestProperty("version", env.getProperty("de.version"));
            conn.setRequestProperty("accessToken", env.getProperty("access.token"));
            conn.setRequestProperty("requestHost", env.getProperty("server.de.host"));
            conn.setRequestProperty("requestPort", env.getProperty("server.port"));
            conn.setRequestProperty("requestProtocol",
                                    env.getProperty("server.de.protocol"));
            PrintWriter pout =
                new PrintWriter(
                    new OutputStreamWriter(
                        conn.getOutputStream(), "UTF-8"),
                    true);
            pout.print(payload);
            pout.flush();
            pout.close();

            InputStream isi = conn.getInputStream();
            InputStreamReader isr = new InputStreamReader(isi);
            int numCharsRead1;
            char[] charArray1 = new char[1024];

            while ((numCharsRead1 = isr.read(charArray1)) > 0) {
                sb.append(charArray1, 0, numCharsRead1);
            }
            isr.close();
            isi.close();
        }
        catch (MalformedURLException e) {
            logger.error("MalformedURLException in restAccessTokenPOST..." +
                         e.getMessage());
            //e.printStackTrace();
        }
        catch (IOException e) {
            logger.error("IOException in restAccessTokenPOST..." +
                         e.getMessage());
            e.printStackTrace();
        }
        catch (Exception e) {
            logger.error("Exception in restAccessTokenPOST..." +
                         e.getMessage());
            e.printStackTrace();
        }
        finally {
            if (null != conn)
                conn.disconnect();
        }
        return sb;
    }

    @Recover
    public String helpHere(ConnectException cause) {
        System.out.println("Recovery place! ConnectException");
        return "Hello";
    }

    @Recover
    public String helpHere(IOException cause) {
        System.out.println("Recovery place! ArithmeticException");
        return "Hello";
    }

    @Recover
    public String helpHere(Exception cause) {
        System.out.println("Recovery place! Exception");
        return "Hello";
    }

    @Recover
    public String helpHere() {
        System.out.println("Recovery place! Exception");
        return "Hello";
    }

    @Recover
    public String helpHere(Throwable cause) {
        System.out.println("Recovery place! Throwable");
        return "Hello";
    }
}

1 Ответ

0 голосов
/ 26 февраля 2019

Учитывая, что вы видите реализацию своей функции restPost(),

@Retryable(value = {IOException.class, ConnectException.class},
           maxAttempts = 4,
           backoff = @Backoff(5000))
public StringBuffer restPost(String restUrl, String payload) {
    try {
        // Your code
    }
    catch(IOException ex){ // These catch block handles the exception
                           // and nothing to throw to retryable.
    }
    catch(MalformedURLException ex){ // More catch blocks that you
                                     // define to handle exception.
    }
}

Здесь вы обрабатываете все исключения, которые могут стать причиной отзыва методов retry и recover.

Примечание : восстанавливаемые методы выполняются только при возникновении исключения, а не обрабатываются ни одним блоком try-catch.

Какое бы исключение не вызывалось методом restPost()обрабатывается самим блоком метода try-catch, и нет исключений, которые были переброшены блоком catch.

Теперь Spring-Retry не может получить какое-либо исключение (поскольку оно обрабатывается методом try-catch блок).Таким образом, метод recovery не будет выполнен.

Решение : вы должны удалить те блоки catch из определения метода, для которого вы хотите выполнить Повторите или Восстановите .

Пожалуйста, сделайте все необходимое, и это будет работать как шарм ...:)

...