Search in sources :

Example 1 with NettyHttpService

use of co.cask.http.NettyHttpService in project cdap by caskdata.

the class WebappProgramRunner method run.

@Override
public ProgramController run(Program program, ProgramOptions options) {
    try {
        ProgramType processorType = program.getType();
        Preconditions.checkNotNull(processorType, "Missing processor type");
        Preconditions.checkArgument(processorType == ProgramType.WEBAPP, "Only WEBAPP process type is supported");
        LOG.info("Initializing Webapp for app {} with jar {}", program.getApplicationId(), program.getJarLocation().getName());
        String serviceName = getServiceName(program.getId());
        Preconditions.checkNotNull(serviceName, "Cannot determine service name for program %s", program.getName());
        LOG.info("Got service name {}", serviceName);
        // Start netty server
        // TODO: add metrics reporting
        JarHttpHandler jarHttpHandler = webappHttpHandlerFactory.createHandler(program.getJarLocation());
        NettyHttpService.Builder builder = new CommonNettyHttpServiceBuilder(cConf, program.getId().toString());
        builder.addHttpHandlers(ImmutableSet.of(jarHttpHandler));
        builder.setUrlRewriter(new WebappURLRewriter(jarHttpHandler));
        builder.setHost(hostname.getCanonicalHostName());
        NettyHttpService httpService = builder.build();
        httpService.startAndWait();
        final InetSocketAddress address = httpService.getBindAddress();
        RunId runId = ProgramRunners.getRunId(options);
        // Register service, and the serving host names.
        final List<Cancellable> cancellables = Lists.newArrayList();
        LOG.info("Webapp {} running on address {} registering as {}", program.getApplicationId(), address, serviceName);
        cancellables.add(serviceAnnouncer.announce(serviceName, address.getPort()));
        for (String hname : getServingHostNames(Locations.newInputSupplier(program.getJarLocation()))) {
            final String sname = ProgramType.WEBAPP.name().toLowerCase() + "/" + hname;
            LOG.info("Webapp {} running on address {} registering as {}", program.getApplicationId(), address, sname);
            cancellables.add(discoveryService.register(ResolvingDiscoverable.of(new Discoverable(sname, address))));
        }
        return new WebappProgramController(program.getId(), runId, httpService, new Cancellable() {

            @Override
            public void cancel() {
                for (Cancellable cancellable : cancellables) {
                    cancellable.cancel();
                }
            }
        });
    } catch (Exception e) {
        throw Throwables.propagate(e);
    }
}
Also used : Discoverable(org.apache.twill.discovery.Discoverable) ResolvingDiscoverable(co.cask.cdap.common.discovery.ResolvingDiscoverable) CommonNettyHttpServiceBuilder(co.cask.cdap.common.http.CommonNettyHttpServiceBuilder) InetSocketAddress(java.net.InetSocketAddress) Cancellable(org.apache.twill.common.Cancellable) NettyHttpService(co.cask.http.NettyHttpService) ProgramType(co.cask.cdap.proto.ProgramType) RunId(org.apache.twill.api.RunId)

Example 2 with NettyHttpService

use of co.cask.http.NettyHttpService in project cdap by caskdata.

the class HttpHandlerGeneratorTest method testHttpHeaders.

@Test
public void testHttpHeaders() throws Exception {
    MetricsContext noOpsMetricsContext = new NoOpMetricsCollectionService().getContext(new HashMap<String, String>());
    HttpHandlerFactory factory = new HttpHandlerFactory("/prefix", noOpsMetricsContext);
    HttpHandler httpHandler = factory.createHttpHandler(TypeToken.of(MyHttpHandler.class), new AbstractDelegatorContext<MyHttpHandler>() {

        @Override
        protected MyHttpHandler createHandler() {
            return new MyHttpHandler();
        }
    });
    NettyHttpService service = NettyHttpService.builder().addHttpHandlers(ImmutableList.of(httpHandler)).build();
    service.startAndWait();
    try {
        InetSocketAddress bindAddress = service.getBindAddress();
        // Make a request with headers that the response should carry first value for each header name
        HttpURLConnection urlConn = (HttpURLConnection) new URL(String.format("http://%s:%d/prefix/p2/echo/firstHeaders", bindAddress.getHostName(), bindAddress.getPort())).openConnection();
        urlConn.addRequestProperty("k1", "v1");
        urlConn.addRequestProperty("k1", "v2");
        urlConn.addRequestProperty("k2", "v2");
        Assert.assertEquals(200, urlConn.getResponseCode());
        Map<String, List<String>> headers = urlConn.getHeaderFields();
        Assert.assertEquals(ImmutableList.of("v1"), headers.get("k1"));
        Assert.assertEquals(ImmutableList.of("v2"), headers.get("k2"));
        // Make a request with headers that the response should carry all values for each header name
        urlConn = (HttpURLConnection) new URL(String.format("http://%s:%d/prefix/p2/echo/allHeaders", bindAddress.getHostName(), bindAddress.getPort())).openConnection();
        urlConn.addRequestProperty("k1", "v1");
        urlConn.addRequestProperty("k1", "v2");
        urlConn.addRequestProperty("k1", "v3");
        urlConn.addRequestProperty("k2", "v2");
        Assert.assertEquals(200, urlConn.getResponseCode());
        headers = urlConn.getHeaderFields();
        // URLConnection always reverse the ordering of the header values.
        Assert.assertEquals(ImmutableList.of("v3", "v2", "v1"), headers.get("k1"));
        Assert.assertEquals(ImmutableList.of("v2"), headers.get("k2"));
    } finally {
        service.stopAndWait();
    }
}
Also used : HttpHandler(co.cask.http.HttpHandler) InetSocketAddress(java.net.InetSocketAddress) MetricsContext(co.cask.cdap.api.metrics.MetricsContext) NoOpMetricsCollectionService(co.cask.cdap.common.metrics.NoOpMetricsCollectionService) URL(java.net.URL) HttpURLConnection(java.net.HttpURLConnection) NettyHttpService(co.cask.http.NettyHttpService) List(java.util.List) ArrayList(java.util.ArrayList) ImmutableList(com.google.common.collect.ImmutableList) Test(org.junit.Test)

Example 3 with NettyHttpService

use of co.cask.http.NettyHttpService in project cdap by caskdata.

the class ServiceHttpServer method createNettyHttpService.

/**
   * Creates a {@link NettyHttpService} from the given host, and list of {@link HandlerDelegatorContext}s
   *
   * @param program Program that contains the handler
   * @param host the host which the service will run on
   * @param delegatorContexts the list {@link HandlerDelegatorContext}
   * @param metricsContext a {@link MetricsContext} for metrics collection
   *
   * @return a NettyHttpService which delegates to the {@link HttpServiceHandler}s to handle the HTTP requests
   */
private NettyHttpService createNettyHttpService(Program program, String host, Iterable<HandlerDelegatorContext> delegatorContexts, MetricsContext metricsContext) {
    // The service URI is always prefixed for routing purpose
    String pathPrefix = String.format("%s/namespaces/%s/apps/%s/services/%s/methods", Constants.Gateway.API_VERSION_3, program.getNamespaceId(), program.getApplicationId(), program.getName());
    String versionId = program.getId().getVersion();
    String versionedPathPrefix = String.format("%s/namespaces/%s/apps/%s/versions/%s/services/%s/methods", Constants.Gateway.API_VERSION_3, program.getNamespaceId(), program.getApplicationId(), versionId, program.getName());
    // Create HttpHandlers which delegate to the HttpServiceHandlers
    HttpHandlerFactory factory = new HttpHandlerFactory(pathPrefix, metricsContext);
    HttpHandlerFactory versionedFactory = new HttpHandlerFactory(versionedPathPrefix, metricsContext);
    List<HttpHandler> nettyHttpHandlers = Lists.newArrayList();
    // get the runtime args from the twill context
    for (HandlerDelegatorContext context : delegatorContexts) {
        nettyHttpHandlers.add(factory.createHttpHandler(context.getHandlerType(), context));
        nettyHttpHandlers.add(versionedFactory.createHttpHandler(context.getHandlerType(), context));
    }
    NettyHttpService.Builder builder = NettyHttpService.builder(program.getName() + "-http").setHost(host).setPort(0).addHttpHandlers(nettyHttpHandlers);
    // These properties are for unit-test only. Currently they are not controllable by the user program
    String threadPoolSize = System.getProperty(THREAD_POOL_SIZE);
    if (threadPoolSize != null) {
        builder.setExecThreadPoolSize(Integer.parseInt(threadPoolSize));
    }
    String threadAliveSec = System.getProperty(THREAD_KEEP_ALIVE_SECONDS);
    if (threadAliveSec != null) {
        builder.setExecThreadKeepAliveSeconds(Long.parseLong(threadAliveSec));
    }
    return builder.build();
}
Also used : HttpHandler(co.cask.http.HttpHandler) HttpHandlerFactory(co.cask.cdap.internal.app.runtime.service.http.HttpHandlerFactory) NettyHttpService(co.cask.http.NettyHttpService)

Example 4 with NettyHttpService

use of co.cask.http.NettyHttpService in project cdap by caskdata.

the class UGIProviderTest method testRemoteUGIProvider.

@Test
public void testRemoteUGIProvider() throws Exception {
    // Starts a mock server to handle remote UGI requests
    final NettyHttpService httpService = NettyHttpService.builder("remoteUGITest").addHttpHandlers(Collections.singleton(new UGIProviderTestHandler())).build();
    httpService.startAndWait();
    setKeytabDir(localKeytabDirPath.getAbsolutePath());
    OwnerAdmin ownerAdmin = getOwnerAdmin();
    // add an owner for stream
    ownerAdmin.add(aliceEntity, aliceKerberosPrincipalId);
    try {
        InMemoryDiscoveryService discoveryService = new InMemoryDiscoveryService();
        discoveryService.register(new Discoverable(Constants.Service.APP_FABRIC_HTTP, httpService.getBindAddress()));
        RemoteUGIProvider ugiProvider = new RemoteUGIProvider(cConf, discoveryService, locationFactory);
        ImpersonationRequest aliceImpRequest = new ImpersonationRequest(aliceEntity, ImpersonatedOpType.OTHER);
        UGIWithPrincipal aliceUGIWithPrincipal = ugiProvider.getConfiguredUGI(aliceImpRequest);
        // Shouldn't be a kerberos UGI
        Assert.assertFalse(aliceUGIWithPrincipal.getUGI().hasKerberosCredentials());
        // Validate the credentials
        Token<? extends TokenIdentifier> token = aliceUGIWithPrincipal.getUGI().getCredentials().getToken(new Text("entity"));
        Assert.assertArrayEquals(aliceEntity.toString().getBytes(StandardCharsets.UTF_8), token.getIdentifier());
        Assert.assertArrayEquals(aliceEntity.toString().getBytes(StandardCharsets.UTF_8), token.getPassword());
        Assert.assertEquals(new Text("entity"), token.getKind());
        Assert.assertEquals(new Text("service"), token.getService());
        token = aliceUGIWithPrincipal.getUGI().getCredentials().getToken(new Text("opType"));
        Assert.assertArrayEquals(aliceImpRequest.getImpersonatedOpType().toString().getBytes(StandardCharsets.UTF_8), token.getIdentifier());
        Assert.assertArrayEquals(aliceImpRequest.getImpersonatedOpType().toString().getBytes(StandardCharsets.UTF_8), token.getPassword());
        Assert.assertEquals(new Text("opType"), token.getKind());
        Assert.assertEquals(new Text("service"), token.getService());
        // Fetch it again, it should return the same UGI due to caching
        Assert.assertSame(aliceUGIWithPrincipal, ugiProvider.getConfiguredUGI(aliceImpRequest));
        // Invalid the cache and fetch it again. A different UGI should be returned
        ugiProvider.invalidCache();
        Assert.assertNotSame(aliceUGIWithPrincipal, ugiProvider.getConfiguredUGI(aliceImpRequest));
    } finally {
        httpService.stopAndWait();
    }
    // cleanup
    ownerAdmin.delete(aliceEntity);
}
Also used : Discoverable(org.apache.twill.discovery.Discoverable) NettyHttpService(co.cask.http.NettyHttpService) Text(org.apache.hadoop.io.Text) InMemoryDiscoveryService(org.apache.twill.discovery.InMemoryDiscoveryService) Test(org.junit.Test)

Example 5 with NettyHttpService

use of co.cask.http.NettyHttpService in project cdap by caskdata.

the class HttpHandlerGeneratorTest method testContentProducer.

@Test
public void testContentProducer() throws Exception {
    MetricsContext noOpsMetricsContext = new NoOpMetricsCollectionService().getContext(new HashMap<String, String>());
    HttpHandlerFactory factory = new HttpHandlerFactory("/content", noOpsMetricsContext);
    // Create the file upload handler and starts a netty server with it
    final File outputDir = TEMP_FOLDER.newFolder();
    HttpHandler httpHandler = factory.createHttpHandler(TypeToken.of(FileHandler.class), new AbstractDelegatorContext<FileHandler>() {

        @Override
        protected FileHandler createHandler() {
            return new FileHandler(outputDir);
        }
    });
    NettyHttpService service = NettyHttpService.builder().addHttpHandlers(ImmutableList.of(httpHandler)).build();
    service.startAndWait();
    try {
        // Generate a 100K file
        File file = TEMP_FOLDER.newFile();
        Files.write(Strings.repeat("0123456789", 10240).getBytes(Charsets.UTF_8), file);
        InetSocketAddress bindAddress = service.getBindAddress();
        // Upload the generated file
        URL uploadURL = new URL(String.format("http://%s:%d/content/upload/test.txt", bindAddress.getHostName(), bindAddress.getPort()));
        HttpURLConnection urlConn = (HttpURLConnection) uploadURL.openConnection();
        try {
            urlConn.setDoOutput(true);
            urlConn.setRequestMethod("PUT");
            Files.copy(file, urlConn.getOutputStream());
            Assert.assertEquals(200, urlConn.getResponseCode());
        } finally {
            urlConn.disconnect();
        }
        // Download the file
        File downloadFile = TEMP_FOLDER.newFile();
        urlConn = (HttpURLConnection) new URL(String.format("http://%s:%d/content/download/test.txt", bindAddress.getHostName(), bindAddress.getPort())).openConnection();
        try {
            ByteStreams.copy(urlConn.getInputStream(), Files.newOutputStreamSupplier(downloadFile));
        } finally {
            urlConn.disconnect();
        }
        // Compare if the file content are the same
        Assert.assertTrue(Files.equal(file, downloadFile));
        // Download a file that doesn't exist
        urlConn = (HttpURLConnection) new URL(String.format("http://%s:%d/content/download/test2.txt", bindAddress.getHostName(), bindAddress.getPort())).openConnection();
        try {
            Assert.assertEquals(500, urlConn.getResponseCode());
        } finally {
            urlConn.disconnect();
        }
        // Upload the file to the POST endpoint. The endpoint should response with the same file content
        downloadFile = TEMP_FOLDER.newFile();
        urlConn = (HttpURLConnection) uploadURL.openConnection();
        try {
            urlConn.setDoOutput(true);
            urlConn.setRequestMethod("POST");
            Files.copy(file, urlConn.getOutputStream());
            ByteStreams.copy(urlConn.getInputStream(), Files.newOutputStreamSupplier(downloadFile));
            Assert.assertEquals(200, urlConn.getResponseCode());
            Assert.assertTrue(Files.equal(file, downloadFile));
        } finally {
            urlConn.disconnect();
        }
    } finally {
        service.stopAndWait();
    }
}
Also used : HttpHandler(co.cask.http.HttpHandler) InetSocketAddress(java.net.InetSocketAddress) MetricsContext(co.cask.cdap.api.metrics.MetricsContext) NoOpMetricsCollectionService(co.cask.cdap.common.metrics.NoOpMetricsCollectionService) URL(java.net.URL) HttpURLConnection(java.net.HttpURLConnection) NettyHttpService(co.cask.http.NettyHttpService) File(java.io.File) Test(org.junit.Test)

Aggregations

NettyHttpService (co.cask.http.NettyHttpService)8 HttpHandler (co.cask.http.HttpHandler)5 InetSocketAddress (java.net.InetSocketAddress)5 Test (org.junit.Test)5 MetricsContext (co.cask.cdap.api.metrics.MetricsContext)4 NoOpMetricsCollectionService (co.cask.cdap.common.metrics.NoOpMetricsCollectionService)4 HttpURLConnection (java.net.HttpURLConnection)3 URL (java.net.URL)3 CommonNettyHttpServiceBuilder (co.cask.cdap.common.http.CommonNettyHttpServiceBuilder)2 File (java.io.File)2 Discoverable (org.apache.twill.discovery.Discoverable)2 AuthorizationClient (co.cask.cdap.client.AuthorizationClient)1 FeatureDisabledException (co.cask.cdap.common.FeatureDisabledException)1 NotFoundException (co.cask.cdap.common.NotFoundException)1 UnauthenticatedException (co.cask.cdap.common.UnauthenticatedException)1 ResolvingDiscoverable (co.cask.cdap.common.discovery.ResolvingDiscoverable)1 HttpHandlerFactory (co.cask.cdap.internal.app.runtime.service.http.HttpHandlerFactory)1 ProgramType (co.cask.cdap.proto.ProgramType)1 NamespaceId (co.cask.cdap.proto.id.NamespaceId)1 Role (co.cask.cdap.proto.security.Role)1