package com.thinkbiganalytics.feedmgr.service.template;
/*-
* #%L
* thinkbig-feed-manager-controller
* %%
* 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.base.Function;
import com.google.common.collect.Collections2;
import com.thinkbiganalytics.feedmgr.rest.model.RegisteredTemplate;
import com.thinkbiganalytics.feedmgr.service.AccessControlledEntityTransform;
import com.thinkbiganalytics.feedmgr.service.EncryptionService;
import com.thinkbiganalytics.json.ObjectMapperSerializer;
import com.thinkbiganalytics.metadata.api.feed.Feed;
import com.thinkbiganalytics.metadata.api.template.FeedManagerTemplate;
import com.thinkbiganalytics.metadata.api.template.FeedManagerTemplateProvider;
import com.thinkbiganalytics.security.rest.controller.SecurityModelTransform;
import com.thinkbiganalytics.support.FeedNameUtil;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;
import javax.inject.Inject;
/**
* Transforms data from the domain {@link FeedManagerTemplate} to the REST object {@link RegisteredTemplate}
*/
public class TemplateModelTransform {
@Inject
private AccessControlledEntityTransform accessControlledEntityTransform;
@Inject
private EncryptionService encryptionService;
public enum TEMPLATE_TRANSFORMATION_TYPE {
WITH_FEED_NAMES, WITHOUT_FEED_NAMES, WITH_SENSITIVE_DATA
}
private void prepareForSave(RegisteredTemplate registeredTemplate) {
//mark password rendertypes as sensitive
registeredTemplate.getProperties().stream().filter(p -> "password".equalsIgnoreCase(p.getRenderType())).forEach(p -> p.setSensitive(true));
encryptSensitivePropertyValues(registeredTemplate);
}
private void encryptSensitivePropertyValues(RegisteredTemplate registeredTemplate) {
registeredTemplate.getProperties().stream().filter(property -> property.isSensitive()).forEach(nifiProperty -> nifiProperty.setValue(encryptionService.encrypt(nifiProperty.getValue())));
}
public final Function<FeedManagerTemplate, RegisteredTemplate>
DOMAIN_TO_REGISTERED_TEMPLATE = DOMAIN_TO_REGISTERED_TEMPLATE(true, false);
public final Function<FeedManagerTemplate, RegisteredTemplate>
DOMAIN_TO_REGISTERED_TEMPLATE_WITHOUT_FEED_NAMES = DOMAIN_TO_REGISTERED_TEMPLATE(false, false);
public final Function<FeedManagerTemplate, RegisteredTemplate>
DOMAIN_TO_REGISTERED_TEMPLATE_WITH_SENSITIVE_DATA = DOMAIN_TO_REGISTERED_TEMPLATE(true, true);
public Function<FeedManagerTemplate, RegisteredTemplate> getTransformationFunction(TEMPLATE_TRANSFORMATION_TYPE transformationType) {
if(transformationType== null) {
transformationType = TEMPLATE_TRANSFORMATION_TYPE.WITH_FEED_NAMES;
}
switch (transformationType) {
case WITH_FEED_NAMES:
return DOMAIN_TO_REGISTERED_TEMPLATE;
case WITH_SENSITIVE_DATA:
return DOMAIN_TO_REGISTERED_TEMPLATE_WITH_SENSITIVE_DATA;
case WITHOUT_FEED_NAMES:
return DOMAIN_TO_REGISTERED_TEMPLATE_WITHOUT_FEED_NAMES;
default:
return DOMAIN_TO_REGISTERED_TEMPLATE;
}
}
@Inject
FeedManagerTemplateProvider templateProvider;
@Inject
private SecurityModelTransform actionsTransform;
public final Function<RegisteredTemplate, FeedManagerTemplate>
REGISTERED_TEMPLATE_TO_DOMAIN =
new Function<RegisteredTemplate, FeedManagerTemplate>() {
@Override
public FeedManagerTemplate apply(RegisteredTemplate registeredTemplate) {
//resolve the id
FeedManagerTemplate.ID domainId = registeredTemplate.getId() != null ? templateProvider.resolveId(registeredTemplate.getId()) : null;
FeedManagerTemplate domain = null;
if (domainId != null) {
domain = templateProvider.findById(domainId);
}
if (domain == null) {
domain = templateProvider.ensureTemplate(registeredTemplate.getTemplateName());
}
domainId = domain.getId();
//clean the order from the template
registeredTemplate.setTemplateOrder(null);
domain.setNifiTemplateId(registeredTemplate.getNifiTemplateId());
domain.setAllowPreconditions(registeredTemplate.isAllowPreconditions());
domain.setName(registeredTemplate.getTemplateName());
domain.setDataTransformation(registeredTemplate.isDataTransformation());
domain.setDefineTable(registeredTemplate.isDefineTable());
domain.setIcon(registeredTemplate.getIcon());
domain.setIconColor(registeredTemplate.getIconColor());
domain.setDescription(registeredTemplate.getDescription());
domain.setOrder(registeredTemplate.getOrder());
domain.setStream(registeredTemplate.isStream());
prepareForSave(registeredTemplate);
String json = ObjectMapperSerializer.serialize(registeredTemplate);
domain.setJson(json);
FeedManagerTemplate.State state = FeedManagerTemplate.State.ENABLED;
try {
if (registeredTemplate.getState() != null) {
state = FeedManagerTemplate.State.valueOf(registeredTemplate.getState());
}
} catch (IllegalArgumentException e) {
// make enabled by default
}
domain.setState(state);
//assign the id back to the ui model
registeredTemplate.setId(domainId.toString());
return domain;
}
};
/**
* Deserialize the JSON of the template
*
* @param json the template json
* @param includeEncryptedProperties if true the encrypted properties will be returned. false will set the property values to ""
* @return the registered template
*/
private RegisteredTemplate deserialize(String json, boolean includeEncryptedProperties) {
RegisteredTemplate template = ObjectMapperSerializer.deserialize(json, RegisteredTemplate.class);
template.getProperties().stream().filter(nifiProperty -> nifiProperty.isSensitive()).forEach(nifiProperty -> {
if (!includeEncryptedProperties) {
nifiProperty.setValue("");
}
// else {
// String val = encryptionService.decrypt(nifiProperty.getValue());
// nifiProperty.setValue(val);
//}
});
return template;
}
public final Function<FeedManagerTemplate, RegisteredTemplate>
DOMAIN_TO_REGISTERED_TEMPLATE(boolean includeFeedNames, boolean includeEncryptedProperties) {
return new Function<FeedManagerTemplate, RegisteredTemplate>() {
@Override
public RegisteredTemplate apply(FeedManagerTemplate domain) {
String json = domain.getJson();
RegisteredTemplate template = deserialize(json, includeEncryptedProperties);
template.setId(domain.getId().toString());
template.setState(domain.getState().name());
template.setNifiTemplateId(domain.getNifiTemplateId());
template.setAllowPreconditions(domain.isAllowPreconditions());
List<Feed> feeds = domain.getFeeds();
template.setFeedsCount(feeds == null ? 0 : feeds.size());
template.setStream(domain.isStream());
if (includeFeedNames && feeds != null) {
template.setFeedNames(feeds.stream().map(feedManagerFeed -> FeedNameUtil.fullName(feedManagerFeed.getCategory().getName(), feedManagerFeed.getName())).collect(
Collectors.toSet()));
}
if (domain.getCreatedTime() != null) {
template.setCreateDate(domain.getCreatedTime().toDate());
}
if (domain.getModifiedTime() != null) {
template.setUpdateDate(domain.getModifiedTime().toDate());
}
template.setOrder(domain.getOrder());
accessControlledEntityTransform.applyAccessControlToRestModel(domain, template);
return template;
}
};
}
public List<RegisteredTemplate> domainToRegisteredTemplateWithFeedNames(Collection<FeedManagerTemplate> domain) {
return new ArrayList<>(Collections2.transform(domain, DOMAIN_TO_REGISTERED_TEMPLATE));
}
public List<RegisteredTemplate> domainToRegisteredTemplate(Collection<FeedManagerTemplate> domain) {
return new ArrayList<>(Collections2.transform(domain, DOMAIN_TO_REGISTERED_TEMPLATE_WITHOUT_FEED_NAMES));
}
public RegisteredTemplate domainToRegisteredTemplateWithFeedNames(FeedManagerTemplate domain) {
return DOMAIN_TO_REGISTERED_TEMPLATE.apply(domain);
}
public RegisteredTemplate domainToRegisteredTemplate(FeedManagerTemplate domain) {
return DOMAIN_TO_REGISTERED_TEMPLATE_WITHOUT_FEED_NAMES.apply(domain);
}
public List<FeedManagerTemplate> registeredTemplateToDomain(Collection<RegisteredTemplate> registeredTemplates) {
return new ArrayList<>(Collections2.transform(registeredTemplates, REGISTERED_TEMPLATE_TO_DOMAIN));
}
}