| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You 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. |
| */ |
| |
| package org.apache.aries.jax.rs.rest.management.test; |
| |
| import static java.util.concurrent.TimeUnit.SECONDS; |
| import static org.osgi.service.jaxrs.runtime.JaxrsServiceRuntimeConstants.JAX_RS_SERVICE_ENDPOINT; |
| |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.io.OutputStream; |
| import java.net.InetSocketAddress; |
| import java.net.URI; |
| import java.net.URL; |
| import java.net.URLConnection; |
| import java.util.Collection; |
| import java.util.concurrent.Executors; |
| import java.util.stream.Stream; |
| |
| import javax.ws.rs.client.Client; |
| import javax.ws.rs.client.ClientBuilder; |
| import javax.ws.rs.client.WebTarget; |
| |
| import org.apache.aries.jax.rs.rest.management.feature.RestManagementFeature; |
| import org.junit.jupiter.api.BeforeEach; |
| import org.junit.jupiter.api.extension.ExtendWith; |
| import org.osgi.framework.BundleContext; |
| import org.osgi.framework.BundleException; |
| import org.osgi.service.jaxrs.runtime.JaxrsServiceRuntime; |
| import org.osgi.test.common.annotation.InjectBundleContext; |
| import org.osgi.test.common.annotation.InjectService; |
| import org.osgi.test.common.service.ServiceAware; |
| import org.osgi.test.junit5.context.BundleContextExtension; |
| import org.osgi.test.junit5.service.ServiceExtension; |
| |
| @ExtendWith({ |
| BundleContextExtension.class, |
| ServiceExtension.class |
| }) |
| public class TestUtil { |
| |
| @InjectService |
| public ClientBuilder clientBuilder; |
| |
| @InjectService( |
| filter = "(%s=*)", |
| filterArguments = JAX_RS_SERVICE_ENDPOINT, |
| timeout = 400l |
| ) |
| public ServiceAware<JaxrsServiceRuntime> jaxrsServiceRuntimeAware; |
| |
| @InjectBundleContext |
| public BundleContext bundleContext; |
| |
| @BeforeEach |
| public void beforeEach(@InjectBundleContext BundleContext bundleContext) { |
| Stream.of(bundleContext.getBundles()).filter(b -> b.getSymbolicName().equals("minor-and-removed-change")).forEach( |
| b -> { |
| try { |
| b.uninstall(); |
| } catch (BundleException e) { |
| throw new RuntimeException(e); |
| } |
| } |
| ); |
| } |
| |
| protected WebTarget createDefaultTarget() { |
| clientBuilder.connectTimeout(600000, SECONDS); |
| clientBuilder.readTimeout(600000, SECONDS); |
| |
| Client client = clientBuilder.build(); |
| |
| client.register(RestManagementFeature.class); |
| |
| return client.target(runtimeURI()); |
| } |
| |
| protected URI runtimeURI() { |
| return runtimeURI("rms"); |
| } |
| |
| protected URI runtimeURI(String... parts) { |
| String[] runtimes = canonicalize( |
| jaxrsServiceRuntimeAware.getServiceReference().getProperty( |
| JAX_RS_SERVICE_ENDPOINT)); |
| |
| if (runtimes.length == 0) { |
| throw new IllegalStateException( |
| "No runtimes could be found on \"osgi.jaxrs.endpoint\" " + |
| "runtime service property "); |
| } |
| |
| String uriString = runtimes[0]; |
| |
| for (String part : parts) { |
| uriString += part + "/"; |
| } |
| |
| return URI.create(uriString); |
| } |
| |
| @SuppressWarnings("unchecked") |
| private static String[] canonicalize(Object propertyValue) { |
| if (propertyValue == null) { |
| return new String[0]; |
| } |
| if (propertyValue instanceof String[]) { |
| return (String[]) propertyValue; |
| } |
| if (propertyValue instanceof Collection) { |
| return ((Collection<String>) propertyValue).toArray(new String[0]); |
| } |
| |
| return new String[]{propertyValue.toString()}; |
| } |
| |
| @SuppressWarnings("restriction") |
| public static class HttpServer implements AutoCloseable { |
| |
| private final com.sun.net.httpserver.HttpServer server; |
| |
| public HttpServer(URL resource, String contentType) throws IOException { |
| server = com.sun.net.httpserver.HttpServer.create( |
| new InetSocketAddress("localhost", 0), 0); |
| |
| server.createContext("/", exchange -> { |
| String requestURI = exchange.getRequestURI().getPath(); |
| |
| if (!requestURI.equals(resource.getPath())) { |
| sendError(exchange, 404, "File not found"); |
| return; |
| } |
| |
| URLConnection connection = resource.openConnection(); |
| exchange.getResponseHeaders().set( |
| "Content-Type", contentType); |
| exchange.sendResponseHeaders( |
| 200, connection.getContentLength()); |
| |
| OutputStream out = exchange.getResponseBody(); |
| InputStream in = connection.getInputStream(); |
| byte[] buf = new byte[4096]; |
| int n; |
| while ((n = in.read(buf)) >= 0) { |
| out.write(buf, 0, n); |
| } |
| out.close(); |
| in.close(); |
| }); |
| server.setExecutor(Executors.newSingleThreadExecutor()); |
| server.start(); |
| } |
| |
| private void sendError( |
| com.sun.net.httpserver.HttpExchange exchange, int code, |
| String description) |
| throws IOException { |
| |
| String message = "HTTP error " + code + ": " + description; |
| byte[] messageBytes = message.getBytes("UTF-8"); |
| |
| exchange.getResponseHeaders().set( |
| "Content-Type", "text/plain; charset=utf-8"); |
| exchange.sendResponseHeaders(code, messageBytes.length); |
| OutputStream out = exchange.getResponseBody(); |
| out.write(messageBytes); |
| out.close(); |
| } |
| |
| public int getPort() { |
| return server.getAddress().getPort(); |
| } |
| |
| @Override |
| public void close() { |
| server.stop(0); |
| } |
| |
| } |
| |
| } |