All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.knotx.assembler.FragmentAssemblerKnotProxyImpl Maven / Gradle / Ivy

Go to download

Core Knot.x module consisting of Server, Repositories, Splitter, Assembler and Gateway.

There is a newer version: 1.6.0
Show newest version
/*
 * Copyright (C) 2016 Cognifide Limited
 *
 * 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.
 */
package io.knotx.assembler;

import com.google.common.collect.Maps;
import io.knotx.dataobjects.ClientResponse;
import io.knotx.dataobjects.Fragment;
import io.knotx.dataobjects.KnotContext;
import io.knotx.fragments.SnippetPatterns;
import io.knotx.knot.AbstractKnotProxy;
import io.netty.handler.codec.http.HttpResponseStatus;
import io.reactivex.Single;
import io.vertx.core.buffer.Buffer;
import io.vertx.core.http.HttpHeaders;
import io.vertx.core.logging.Logger;
import io.vertx.core.logging.LoggerFactory;
import io.vertx.reactivex.core.MultiMap;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import org.apache.commons.lang3.StringUtils;

public class FragmentAssemblerKnotProxyImpl extends AbstractKnotProxy {

  private static final Logger LOGGER = LoggerFactory.getLogger(FragmentAssemblerKnotProxyImpl.class);

  private final SnippetPatterns patterns;

  private FragmentAssemblerOptions options;

  private FragmentAssemblerFallbackHandler fallbackHandler;

  public FragmentAssemblerKnotProxyImpl(FragmentAssemblerOptions options) {
    this.options = options;
    this.patterns = new SnippetPatterns(options.getSnippetOptions());
    this.fallbackHandler = new FragmentAssemblerFallbackHandler(options);
  }

  @Override
  protected Single processRequest(KnotContext knotContext) {
    if (hasFragments(knotContext)) {
      try {
        Map fallbackFragmentCache = Maps.newHashMap();
        String joinedFragments = knotContext.getFragments().stream()
            .filter(f -> !f.isFallback())
            .map(f -> processFragment(f, knotContext, fallbackFragmentCache))
            .collect(Collectors.joining());

        return Single.just(createSuccessResponse(knotContext, joinedFragments));
      } catch (Exception ex) {
        LOGGER.error("Exception happened during Fragment assembly.", ex);
        return Single.just(processError(knotContext, ex));
      }
    } else {
      LOGGER.error("Fragments are empty or not exists in KnotContext.");
      return Single.just(processError(knotContext, null));
    }
  }

  private String processFragment(Fragment fragment, KnotContext knotContext,Map fallbackFragmentCache) {
    return fragment.failed() && fragment.fallback().isPresent() ? fallbackHandler.applyFallback(fragment, knotContext, fallbackFragmentCache)
        : options.getUnprocessedStrategy().get(fragment, patterns);
  }

  private boolean hasFragments(KnotContext knotContext) {
    return knotContext.getFragments() != null && !knotContext.getFragments().isEmpty();
  }

  @Override
  protected boolean shouldProcess(Set knots) {
    return true;
  }

  @Override
  protected KnotContext processError(KnotContext knotContext, Throwable error) {
    ClientResponse errorResponse = new ClientResponse()
        .setStatusCode(HttpResponseStatus.INTERNAL_SERVER_ERROR.code());

    return new KnotContext()
        .setClientRequest(knotContext.getClientRequest())
        .setClientResponse(errorResponse);
  }

  private KnotContext createSuccessResponse(KnotContext inputContext, String renderedContent) {
    ClientResponse clientResponse = inputContext.getClientResponse();
    if (StringUtils.isBlank(renderedContent)) {
      clientResponse.setStatusCode(HttpResponseStatus.NO_CONTENT.code());
    } else {
      MultiMap headers = clientResponse.getHeaders();
      headers.add(HttpHeaders.CONTENT_LENGTH.toString().toLowerCase(),
          Integer.toString(renderedContent.length()));

      clientResponse.setBody(Buffer.buffer(renderedContent)).setHeaders(headers);
      clientResponse.setStatusCode(HttpResponseStatus.OK.code());
    }

    return new KnotContext()
        .setClientRequest(inputContext.getClientRequest())
        .setClientResponse(clientResponse);
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy