View Javadoc
1   /*
2    * Copyright 2012-2021 CodeLibs Project and the Others.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
13   * either express or implied. See the License for the specific language
14   * governing permissions and limitations under the License.
15   */
16  package org.codelibs.fess.app.service;
17  
18  import java.io.PrintWriter;
19  import java.util.List;
20  
21  import javax.annotation.Resource;
22  
23  import org.apache.commons.io.output.StringBuilderWriter;
24  import org.apache.commons.lang3.StringUtils;
25  import org.codelibs.core.beans.util.BeanUtil;
26  import org.codelibs.core.lang.StringUtil;
27  import org.codelibs.fess.Constants;
28  import org.codelibs.fess.app.pager.FailureUrlPager;
29  import org.codelibs.fess.es.config.cbean.FailureUrlCB;
30  import org.codelibs.fess.es.config.exbhv.FailureUrlBhv;
31  import org.codelibs.fess.es.config.exentity.CrawlingConfig;
32  import org.codelibs.fess.es.config.exentity.FailureUrl;
33  import org.codelibs.fess.exception.ContainerNotAvailableException;
34  import org.codelibs.fess.helper.SystemHelper;
35  import org.codelibs.fess.mylasta.direction.FessConfig;
36  import org.codelibs.fess.util.ComponentUtil;
37  import org.dbflute.cbean.result.PagingResultBean;
38  import org.dbflute.optional.OptionalEntity;
39  
40  public class FailureUrlService {
41  
42      @Resource
43      protected FailureUrlBhv failureUrlBhv;
44  
45      @Resource
46      protected FessConfig fessConfig;
47  
48      public List<FailureUrl> getFailureUrlList(final FailureUrlPager failureUrlPager) {
49  
50          final PagingResultBean<FailureUrl> failureUrlList = failureUrlBhv.selectPage(cb -> {
51              cb.paging(failureUrlPager.getPageSize(), failureUrlPager.getCurrentPageNumber());
52              setupListCondition(cb, failureUrlPager);
53          });
54  
55          // update pager
56          BeanUtil.copyBeanToBean(failureUrlList, failureUrlPager, option -> option.include(Constants.PAGER_CONVERSION_RULE));
57          failureUrlPager.setPageNumberList(failureUrlList.pageRange(op -> {
58              op.rangeSize(fessConfig.getPagingPageRangeSizeAsInteger());
59          }).createPageNumberList());
60  
61          return failureUrlList;
62      }
63  
64      public OptionalEntity<FailureUrl> getFailureUrl(final String id) {
65          return failureUrlBhv.selectByPK(id);
66      }
67  
68      public void store(final FailureUrl failureUrl) {
69  
70          failureUrlBhv.insertOrUpdate(failureUrl, op -> {
71              op.setRefreshPolicy(Constants.TRUE);
72          });
73  
74      }
75  
76      public void delete(final FailureUrl failureUrl) {
77  
78          failureUrlBhv.delete(failureUrl, op -> {
79              op.setRefreshPolicy(Constants.TRUE);
80          });
81  
82      }
83  
84      protected void setupListCondition(final FailureUrlCB cb, final FailureUrlPager failureUrlPager) {
85          if (failureUrlPager.id != null) {
86              cb.query().docMeta().setId_Equal(failureUrlPager.id);
87          }
88          // TODO Long, Integer, String supported only.
89  
90          // setup condition
91          cb.query().addOrderBy_LastAccessTime_Desc();
92  
93          buildSearchCondition(failureUrlPager, cb);
94      }
95  
96      public void deleteAll(final FailureUrlPager failureUrlPager) {
97          failureUrlBhv.queryDelete(cb -> {
98              buildSearchCondition(failureUrlPager, cb);
99          });
100     }
101 
102     private void buildSearchCondition(final FailureUrlPager failureUrlPager, final FailureUrlCB cb) {
103         // search
104         if (StringUtil.isNotBlank(failureUrlPager.url)) {
105             cb.query().setUrl_Wildcard(failureUrlPager.url);
106         }
107 
108         if (StringUtil.isNotBlank(failureUrlPager.errorCountMax)) {
109             cb.query().setErrorCount_LessEqual(Integer.parseInt(failureUrlPager.errorCountMax));
110         }
111         if (StringUtil.isNotBlank(failureUrlPager.errorCountMin)) {
112             cb.query().setErrorCount_GreaterEqual(Integer.parseInt(failureUrlPager.errorCountMin));
113         }
114 
115         if (StringUtil.isNotBlank(failureUrlPager.errorName)) {
116             cb.query().setErrorName_Wildcard(failureUrlPager.errorName);
117         }
118 
119     }
120 
121     public void deleteByConfigId(final String configId) {
122         failureUrlBhv.queryDelete(cb -> {
123             cb.query().setConfigId_Equal(configId);
124         });
125     }
126 
127     public void store(final CrawlingConfig crawlingConfig, final String errorName, final String url, final Throwable e) {
128         if (e instanceof ContainerNotAvailableException) {
129             return;
130         }
131 
132         final FailureUrlBhv bhv = ComponentUtil.getComponent(FailureUrlBhv.class);
133         final FailureUrl failureUrl = bhv.selectEntity(cb -> {
134             cb.query().setUrl_Equal(url);
135             if (crawlingConfig != null) {
136                 cb.query().setConfigId_Equal(crawlingConfig.getConfigId());
137             }
138         }).map(entity -> {
139             entity.setErrorCount(entity.getErrorCount() + 1);
140             return entity;
141         }).orElseGet(() -> {
142             final FailureUrl entity = new FailureUrl();
143             entity.setErrorCount(1);
144             entity.setUrl(url);
145             if (crawlingConfig != null) {
146                 entity.setConfigId(crawlingConfig.getConfigId());
147             }
148             return entity;
149         });
150 
151         failureUrl.setErrorName(errorName);
152         failureUrl.setErrorLog(StringUtils.abbreviate(getStackTrace(e), 4000));
153         failureUrl.setLastAccessTime(ComponentUtil.getSystemHelper().getCurrentTimeAsLong());
154         failureUrl.setThreadName(Thread.currentThread().getName());
155 
156         bhv.insertOrUpdate(failureUrl, op -> {
157             op.setRefreshPolicy(Constants.TRUE);
158         });
159     }
160 
161     private String getStackTrace(final Throwable t) {
162         final SystemHelper systemHelper = ComponentUtil.getSystemHelper();
163         final StringBuilderWriter sw = new StringBuilderWriter();
164         final PrintWriter pw = new PrintWriter(sw, true);
165         t.printStackTrace(pw);
166         return systemHelper.abbreviateLongText(sw.toString());
167     }
168 }