CallableHttpHead.java

1
package com.jsql.model.accessible;
2
3
import com.jsql.model.InjectionModel;
4
import com.jsql.model.bean.util.Header;
5
import com.jsql.model.bean.util.Interaction;
6
import com.jsql.model.bean.util.Request;
7
import com.jsql.util.ConnectionUtil;
8
import com.jsql.util.LogLevelUtil;
9
import org.apache.commons.lang3.StringUtils;
10
import org.apache.logging.log4j.LogManager;
11
import org.apache.logging.log4j.Logger;
12
13
import java.net.URI;
14
import java.net.http.HttpClient;
15
import java.net.http.HttpRequest;
16
import java.net.http.HttpRequest.BodyPublishers;
17
import java.net.http.HttpResponse;
18
import java.net.http.HttpResponse.BodyHandlers;
19
import java.time.Duration;
20
import java.util.AbstractMap.SimpleEntry;
21
import java.util.EnumMap;
22
import java.util.Map;
23
import java.util.Objects;
24
import java.util.Optional;
25
import java.util.concurrent.Callable;
26
import java.util.stream.Stream;
27
28
/**
29
 * Thread unit to test if an administration page exists on the server.
30
 * The process can be cancelled by the user.
31
 */
32
public class CallableHttpHead implements Callable<CallableHttpHead> {
33
    
34
    /**
35
     * Log4j logger sent to view.
36
     */
37
    private static final Logger LOGGER = LogManager.getRootLogger();
38
    
39
    /**
40
     * URL to an administration page on the website to get tested.
41
     */
42
    private final String urlAdminPage;
43
    
44
    /**
45
     * HTTP header response code.
46
     */
47
    private String responseCodeHttp = StringUtils.EMPTY;
48
49
    private final InjectionModel injectionModel;
50
51
    private final String metadataInjectionProcess;
52
    
53
    /**
54
     * Create a callable to find admin page.
55
     * @param urlAdminPage URL of admin page
56
     */
57
    public CallableHttpHead(String urlAdminPage, InjectionModel injectionModel, String metadataInjectionProcess) {
58
        
59
        this.urlAdminPage = urlAdminPage;
60
        this.injectionModel= injectionModel;
61
        this.metadataInjectionProcess= metadataInjectionProcess;
62
    }
63
64
    /**
65
     * Call URL to a administration page in HEAD mode and send the result back to view.
66
     */
67
    @Override
68
    public CallableHttpHead call() {
69
        
70 1 1. call : negated conditional → NO_COVERAGE
        if (this.injectionModel.getResourceAccess().isSearchAdminStopped()) {
71 1 1. call : replaced return value with null for com/jsql/model/accessible/CallableHttpHead::call → NO_COVERAGE
            return this;
72
        }
73
        
74
        try {
75
            var builderHttpRequest = HttpRequest.newBuilder()
76
                .uri(URI.create(this.urlAdminPage))
77
                .method("HEAD", BodyPublishers.noBody())
78
                .timeout(Duration.ofSeconds(4));
79
            
80
            Stream.of(
81
                this.injectionModel.getMediatorUtils().getParameterUtil().getHeaderFromEntries()
82
                .split("\\\\r\\\\n")
83
            )
84
            .map(e -> {
85
                
86 1 1. lambda$call$0 : negated conditional → NO_COVERAGE
                if (e.split(":").length == 2) {
87
                    
88 1 1. lambda$call$0 : replaced return value with null for com/jsql/model/accessible/CallableHttpHead::lambda$call$0 → NO_COVERAGE
                    return new SimpleEntry<>(
89
                        e.split(":")[0],
90
                        e.split(":")[1]
91
                    );
92
                } else {
93
                    
94
                    return null;
95
                }
96
            })
97
            .filter(Objects::nonNull)
98 1 1. call : removed call to java/util/stream/Stream::forEach → NO_COVERAGE
            .forEach(e -> builderHttpRequest.header(e.getKey(), e.getValue()));
99
            
100
            var httpRequest = builderHttpRequest.build();
101
            
102
            var httpClient = HttpClient.newBuilder()
103
                .connectTimeout(Duration.ofSeconds(4))
104
                .build();
105
            
106
            HttpResponse<Void> response = httpClient.send(httpRequest, BodyHandlers.discarding());
107
108
            this.responseCodeHttp = ""+ response.statusCode();
109
110
            Map<Header, Object> msgHeader = new EnumMap<>(Header.class);
111
            msgHeader.put(Header.URL, this.urlAdminPage);
112
            msgHeader.put(Header.POST, StringUtils.EMPTY);
113
            msgHeader.put(Header.HEADER, ConnectionUtil.getHeadersMap(httpRequest.headers()));
114
            msgHeader.put(Header.RESPONSE, ConnectionUtil.getHeadersMap(response));
115
            msgHeader.put(Header.METADATA_PROCESS, this.metadataInjectionProcess);
116
            
117
            var request = new Request();
118 1 1. call : removed call to com/jsql/model/bean/util/Request::setMessage → NO_COVERAGE
            request.setMessage(Interaction.MESSAGE_HEADER);
119 1 1. call : removed call to com/jsql/model/bean/util/Request::setParameters → NO_COVERAGE
            request.setParameters(msgHeader);
120 1 1. call : removed call to com/jsql/model/InjectionModel::sendToViews → NO_COVERAGE
            this.injectionModel.sendToViews(request);
121
            
122
        } catch (InterruptedException e) {
123
            
124
            LOGGER.log(LogLevelUtil.IGNORE, e, e);
125 1 1. call : removed call to java/lang/Thread::interrupt → NO_COVERAGE
            Thread.currentThread().interrupt();
126
            
127
        } catch (Exception e) {
128
            
129
            var eMessageImplicit = String.format(
130
                "Problem connecting to %s (implicit reason): %s", 
131
                this.urlAdminPage,
132
                InjectionModel.getImplicitReason(e)
133
            );
134
            
135
            String eMessage = Optional.ofNullable(e.getMessage()).orElse(eMessageImplicit);
136
            
137
            LOGGER.log(LogLevelUtil.CONSOLE_ERROR, eMessage);
138
        }
139
        
140 1 1. call : replaced return value with null for com/jsql/model/accessible/CallableHttpHead::call → NO_COVERAGE
        return this;
141
    }
142
143
    /**
144
     * Check if HTTP response is either 2xx or 3xx, which corresponds to
145
     * a acceptable response from the website.
146
     * @return true if HTTP code start with 2 or 3
147
     */
148
    public boolean isHttpResponseOk() {
149 2 1. isHttpResponseOk : replaced boolean return with false for com/jsql/model/accessible/CallableHttpHead::isHttpResponseOk → NO_COVERAGE
2. isHttpResponseOk : replaced boolean return with true for com/jsql/model/accessible/CallableHttpHead::isHttpResponseOk → NO_COVERAGE
        return this.responseCodeHttp.matches("[23]\\d\\d");
150
    }
151
    
152
    
153
    // Getters
154
    
155
    public String getUrl() {
156 1 1. getUrl : replaced return value with "" for com/jsql/model/accessible/CallableHttpHead::getUrl → NO_COVERAGE
        return this.urlAdminPage;
157
    }
158
}

Mutations

70

1.1
Location : call
Killed by : none
negated conditional → NO_COVERAGE

71

1.1
Location : call
Killed by : none
replaced return value with null for com/jsql/model/accessible/CallableHttpHead::call → NO_COVERAGE

86

1.1
Location : lambda$call$0
Killed by : none
negated conditional → NO_COVERAGE

88

1.1
Location : lambda$call$0
Killed by : none
replaced return value with null for com/jsql/model/accessible/CallableHttpHead::lambda$call$0 → NO_COVERAGE

98

1.1
Location : call
Killed by : none
removed call to java/util/stream/Stream::forEach → NO_COVERAGE

118

1.1
Location : call
Killed by : none
removed call to com/jsql/model/bean/util/Request::setMessage → NO_COVERAGE

119

1.1
Location : call
Killed by : none
removed call to com/jsql/model/bean/util/Request::setParameters → NO_COVERAGE

120

1.1
Location : call
Killed by : none
removed call to com/jsql/model/InjectionModel::sendToViews → NO_COVERAGE

125

1.1
Location : call
Killed by : none
removed call to java/lang/Thread::interrupt → NO_COVERAGE

140

1.1
Location : call
Killed by : none
replaced return value with null for com/jsql/model/accessible/CallableHttpHead::call → NO_COVERAGE

149

1.1
Location : isHttpResponseOk
Killed by : none
replaced boolean return with false for com/jsql/model/accessible/CallableHttpHead::isHttpResponseOk → NO_COVERAGE

2.2
Location : isHttpResponseOk
Killed by : none
replaced boolean return with true for com/jsql/model/accessible/CallableHttpHead::isHttpResponseOk → NO_COVERAGE

156

1.1
Location : getUrl
Killed by : none
replaced return value with "" for com/jsql/model/accessible/CallableHttpHead::getUrl → NO_COVERAGE

Active mutators

Tests examined


Report generated by PIT 1.16.1