package com.thinkbiganalytics.nifi.v1.rest.client; /*- * #%L * thinkbig-nifi-rest-client-v1 * %% * Copyright (C) 2017 ThinkBig Analytics * %% * 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. * #L% */ import com.google.common.util.concurrent.Uninterruptibles; import com.thinkbiganalytics.nifi.rest.client.NiFiProcessorsRestClient; import com.thinkbiganalytics.nifi.rest.client.NifiClientRuntimeException; import com.thinkbiganalytics.nifi.rest.client.NifiComponentNotFoundException; import com.thinkbiganalytics.nifi.rest.support.NifiConstants; import org.apache.nifi.web.api.dto.ProcessorDTO; import org.apache.nifi.web.api.dto.RevisionDTO; import org.apache.nifi.web.api.entity.ProcessorEntity; import java.util.Optional; import java.util.concurrent.TimeUnit; import javax.annotation.Nonnull; import javax.ws.rs.NotFoundException; /** * Implements a {@link NiFiProcessorsRestClient} for communicating with NiFi v1.0. */ public class NiFiProcessorsRestClientV1 implements NiFiProcessorsRestClient { /** * Base path for processor requests */ private static final String BASE_PATH = "/processors/"; /** * REST client for communicating with NiFi */ private final NiFiRestClientV1 client; /** * Constructs a {@code NiFiProcessorsRestClientV1} with the specified NiFi REST client. * * @param client the REST client */ public NiFiProcessorsRestClientV1(@Nonnull final NiFiRestClientV1 client) { this.client = client; } @Nonnull @Override public Optional<ProcessorDTO> findById(@Nonnull final String processGroupId, @Nonnull final String processorId) { return findEntityById(processorId).map(ProcessorEntity::getComponent); } @Nonnull @Override public ProcessorDTO update(@Nonnull final ProcessorDTO processor) { return findEntityById(processor.getId()) .flatMap(current -> { final ProcessorEntity entity = new ProcessorEntity(); entity.setComponent(processor); final RevisionDTO revision = new RevisionDTO(); revision.setVersion(current.getRevision().getVersion()); entity.setRevision(revision); try { return Optional.of(client.put(BASE_PATH + processor.getId(), entity, ProcessorEntity.class).getComponent()); } catch (final NotFoundException e) { return Optional.empty(); } }) .orElseThrow(() -> new NifiComponentNotFoundException(processor.getId(), NifiConstants.NIFI_COMPONENT_TYPE.PROCESSOR, null)); } /** * @param processor the processor * @param retries number of retries, at least 0; will try {@code retries} + 1 times * @param timeout duration to wait between retries * @param timeUnit unit of time for {@code timeout} */ @Nonnull @Override public ProcessorDTO updateWithRetry(@Nonnull ProcessorDTO processor, final int retries, final int timeout, @Nonnull final TimeUnit timeUnit) { Exception lastError = null; for (int count = 0; count <= retries; ++count) { try { return update(processor); } catch (final Exception e) { lastError = e; Uninterruptibles.sleepUninterruptibly(timeout, timeUnit); } } // Give up throw new NifiClientRuntimeException("Unable to update processor: " + processor.getId(), lastError); } /** * Gets a processor entity. * * @param id the processor id * @return the processor entity, if found */ @Nonnull private Optional<ProcessorEntity> findEntityById(@Nonnull final String id) { try { return Optional.ofNullable(client.get(BASE_PATH + id, null, ProcessorEntity.class)); } catch (final NotFoundException e) { return Optional.empty(); } } }