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

Mutations

64

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

65

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

78

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

79

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

88

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

105

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

106

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

107

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

110

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

121

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

130

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

137

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.19.1