aboutsummaryrefslogtreecommitdiffstats
path: root/main/src/test/java/org/onap/policy/pdpx/main/CommonRest.java
blob: 7bdd4c473002ed1d28c72910d53242ff7168007d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
/*-
 * ============LICENSE_START=======================================================
 * ONAP
 * ================================================================================
 * Copyright (C) 2019, 2021 AT&T Intellectual Property. All rights reserved.
 * Modifications Copyright (C) 2019,2023 Nordix Foundation.
 * ================================================================================
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * SPDX-License-Identifier: Apache-2.0
 * ============LICENSE_END=========================================================
 */

package org.onap.policy.pdpx.main;

import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.security.SecureRandom;
import java.util.concurrent.atomic.AtomicBoolean;
import javax.net.ssl.SSLContext;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Invocation;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.MediaType;
import org.glassfish.jersey.client.authentication.HttpAuthenticationFeature;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.onap.policy.common.utils.network.NetworkUtil;
import org.onap.policy.common.utils.resources.ResourceUtils;
import org.onap.policy.common.utils.security.SelfSignedKeyStore;
import org.onap.policy.pdpx.main.rest.XacmlPdpStatisticsManager;
import org.onap.policy.pdpx.main.startstop.Main;
import org.onap.policy.pdpx.main.startstop.XacmlPdpActivator;
import org.springframework.test.util.ReflectionTestUtils;

/**
 * Common base class for REST service tests.
 */
public class CommonRest {

    /**
     * Full path to the config file.
     */
    public static final String CONFIG_FILE;

    /**
     * Path corresponding to {@link #CONFIG_FILE}.
     */
    private static final Path CONFIG_PATH;

    /**
     * Contents read from the "standard" config file, which still contains ${xxx}
     * place-holders.
     */
    private static final String STD_CONFIG;

    /**
     * Port that was last allocated for the server.
     */
    protected static int port;

    /**
     * "Main" that was last started.
     */
    private static Main main;

    /**
     * Records the "alive" state of the activator while it's temporarily updated by
     * various junit tests. The {@link #tearDown()} method restores the "alive" state back
     * to this value.
     */
    private boolean activatorWasAlive;

    static {
        try {
            File file = new File(ResourceUtils.getFilePath4Resource("parameters/XacmlPdpConfigParameters_Std.json"));
            STD_CONFIG = new String(Files.readAllBytes(file.toPath()), StandardCharsets.UTF_8);

            file = new File(file.getParentFile(), "Test_XacmlPdpConfigParameters.json");
            file.deleteOnExit();

            CONFIG_FILE = file.getAbsolutePath();
            CONFIG_PATH = new File(CONFIG_FILE).toPath();

        } catch (IOException e) {
            throw new ExceptionInInitializerError(e);
        }
    }

    /**
     * Configures system properties and creates a JSON config file.
     *
     * @throws Exception if an error occurs
     */
    @BeforeClass
    public static void setUpBeforeClass() throws Exception {
        System.setProperty("javax.net.ssl.keyStore", new SelfSignedKeyStore().getKeystoreName());
        System.setProperty("javax.net.ssl.keyStorePassword", SelfSignedKeyStore.KEYSTORE_PASSWORD);

        System.setProperty("org.eclipse.jetty.util.log.class", "org.eclipse.jetty.util.log.StdErrLog");
        System.setProperty("org.eclipse.jetty.LEVEL", "OFF");

        writeJsonConfig();

        final String[] xacmlPdpConfigParameters = {"-c", CommonRest.CONFIG_FILE};
        main = new Main(xacmlPdpConfigParameters);

        // start xacml rest controller
        XacmlPdpActivator.getCurrent().enableApi();

        if (!NetworkUtil.isTcpPortOpen("localhost", port, 20, 1000L)) {
            throw new IllegalStateException("server is not listening on port " + port);
        }
    }

    /**
     * Stops the "Main".
     */
    @AfterClass
    public static void tearDownAfterClass() {
        stopMain();
    }

    /**
     * Resets the statistics.
     */
    @Before
    public void setUp() {
        activatorWasAlive = XacmlPdpActivator.getCurrent().isAlive();
        XacmlPdpStatisticsManager.getCurrent().resetAllStatistics();
    }

    /**
     * Restores the "alive" status of the activator.
     */
    @After
    public void tearDown() {
        markActivator(activatorWasAlive);
    }

    /**
     * Stops the "main".
     */
    protected static void stopMain() {
        main.shutdown();
    }

    /**
     * Writes a JSON config file, substituting an allocated port number for occurrences of
     * "${port}".
     *
     * @return the allocated server port
     * @throws IOException if the config file cannot be created
     */
    public static int writeJsonConfig() throws IOException {
        port = NetworkUtil.allocPort();

        String config = STD_CONFIG.replace("${port}", String.valueOf(port));
        Files.write(CONFIG_PATH, config.getBytes(StandardCharsets.UTF_8));

        return port;
    }

    /**
     * Sends an HTTPS request to an endpoint of the PDP's REST API.
     *
     * @param endpoint target endpoint
     * @return a request builder
     * @throws Exception if an error occurs
     */
    protected Invocation.Builder sendHttpsRequest(final String endpoint) throws Exception {
        // always trust the certificate
        final SSLContext sc = SSLContext.getInstance("TLSv1.2");
        sc.init(null, NetworkUtil.getAlwaysTrustingManager(), new SecureRandom());

        // always trust the host name
        final ClientBuilder clientBuilder =
                        ClientBuilder.newBuilder().sslContext(sc).hostnameVerifier((host, session) -> true);

        final Client client = clientBuilder.build();
        final HttpAuthenticationFeature feature = HttpAuthenticationFeature.basic("healthcheck", "zb!XztG34");
        client.register(feature);

        final WebTarget webTarget = client.target("https://localhost:" + port + "/policy/pdpx/v1/" + endpoint);

        return webTarget.request(MediaType.APPLICATION_JSON);
    }

    /**
     * Mark the activator as dead, but leave its REST server running.
     */
    protected void markActivatorDead() {
        markActivator(false);
    }

    /**
     * Changes the internal "alive" status of the activator to a new value.
     *
     * @param newAlive the new "alive" status
     */
    private void markActivator(boolean newAlive) {
        Object manager = ReflectionTestUtils.getField(XacmlPdpActivator.getCurrent(), "serviceManager");
        AtomicBoolean running = (AtomicBoolean) ReflectionTestUtils.getField(manager, "running");
        running.set(newAlive);
    }
}