Merge branch 'develop' into NIFI-25

Conflicts:
	nifi/nifi-assembly/NOTICE
	nifi/nifi-nar-bundles/pom.xml
This commit is contained in:
Mark Payne 2015-04-10 09:42:53 -04:00
commit 93a121044b
875 changed files with 35321 additions and 15267 deletions

View File

@ -4,8 +4,3 @@ Copyright 2014-2015 The Apache Software Foundation
This product includes software developed at
The Apache Software Foundation (http://www.apache.org/).
The source release of this product bundles a modified
version of PathCompiler from https://github.com/jayway/JsonPath
The following notice information applies
Copyright 2011 Kalle Stenflo, Jochen Berger

View File

@ -18,7 +18,7 @@
<parent>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi</artifactId>
<version>0.0.2-incubating-SNAPSHOT</version>
<version>0.1.0-incubating-SNAPSHOT</version>
</parent>
<artifactId>nifi-api</artifactId>
<packaging>jar</packaging>

View File

@ -0,0 +1,42 @@
/*
* 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.nifi.annotation.behavior;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Indicates that a component has more than one dynamic property
*
* @author
*
*/
@Documented
@Target({ ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface DynamicProperties {
/**
* A list of the dynamic properties supported by a component
* @return A list of the dynamic properties supported by a component
*/
public DynamicProperty[] value();
}

View File

@ -0,0 +1,67 @@
/*
* 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.nifi.annotation.behavior;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.apache.nifi.components.ConfigurableComponent;
/**
* An annotation that may be placed on a {@link ConfigurableComponent} to
* indicate that it supports a dynamic property.
*
* @author
*
*/
@Documented
@Target({ ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface DynamicProperty {
/**
* A description of what the name of the dynamic property may be
*
* @return A description of what the name of the dynamic property may be
*/
public String name();
/**
* Indicates whether or not the dynamic property supports expression
* language
*
* @return whether or not the dynamic property supports expression
* language
*/
public boolean supportsExpressionLanguage() default false;
/**
* A description of what the value of the dynamic property may be
* @return a description of what the value of the dynamic property may be
*/
public String value();
/**
* Provides a description of what the meaning of the property is, and what the expected values are
* @return a description of what the meaning of the property is, and what the expected values are
*/
public String description();
}

View File

@ -0,0 +1,56 @@
/*
* 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.nifi.annotation.behavior;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.apache.nifi.components.PropertyDescriptor;
import org.apache.nifi.processor.Processor;
import org.apache.nifi.processor.Relationship;
/**
* Annotation to indicate that a {@link Processor} supports dynamic
* relationship. A dynamic {@link Relationship} is one where the relationship is
* generated based on a user defined {@link PropertyDescriptor}
*
* @author
*
*/
@Documented
@Target({ ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface DynamicRelationship {
/**
* Describes the name(s) of the dynamic relationship(s)
*
* @return a description of the name(s) of the dynamic relationship(s)
*/
public String name();
/**
* Describes the data that should be routed to the dynamic relationship(s)
*
* @return a description the data that should be routed to the dynamic relationship(s)
*/
public String description();
}

View File

@ -0,0 +1,50 @@
/*
* 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.nifi.annotation.behavior;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Annotation that may be placed on a {@link org.apache.nifi.processor.Processor Processor}
* indicating that this processor reads a specific FlowFile attribute.
*
* @author
*
*/
@Documented
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface ReadsAttribute {
/**
* The FlowFile attribute that is being read
* @return
*/
public String attribute();
/**
* The description of how the attribute is being used
* @return
*/
public String description() default "";
}

View File

@ -0,0 +1,44 @@
/*
* 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.nifi.annotation.behavior;
import org.apache.nifi.annotation.behavior.ReadsAttribute;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Annotation that may be placed on a {@link org.apache.nifi.processor.Processor Processor}
* indicating that this processor reads specific FlowFile attributes.
*
* @author
*
*/
@Documented
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface ReadsAttributes {
/**
* A list of attributes that may be read
* @return
*/
public ReadsAttribute[] value();
}

View File

@ -0,0 +1,51 @@
/*
* 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.nifi.annotation.behavior;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Annotation that may be placed on a {@link org.apache.nifi.processor.Processor Processor}
* indicating that this processor writes/updates a specific FlowFile attribute.
*
* @author
*
*/
@Documented
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface WritesAttribute {
/**
* The FlowFile attribute that is being created or updated
* @return
*/
public String attribute();
/**
* A description of what is being written to the FlowFile attribute
* @return
*/
public String description() default "";
}

View File

@ -0,0 +1,44 @@
/*
* 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.nifi.annotation.behavior;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Annotation that may be placed on a {@link org.apache.nifi.processor.Processor Processor}
* indicating that this processor writes/updates specific FlowFile attributes.
*
* @author
*
*/
@Documented
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface WritesAttributes {
/**
* A list of FlowFile attributes that may be written or updated
* @return
*/
public WritesAttribute[] value();
}

View File

@ -0,0 +1,59 @@
/*
* 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.nifi.annotation.documentation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.apache.nifi.components.ConfigurableComponent;
/**
* Annotation that may be placed on a
* {@link org.apache.nifi.processor.Processor Processor},
* {@link org.apache.nifi.controller.ControllerService ControllerService}, or
* {@link org.apache.nifi.reporting.ReportingTask ReportingTask} that indicates
* this component is related to the components listed.
*
* @author
*
*/
@Documented
@Target({ ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface SeeAlso {
/**
* Classes you want to link to.
*
* @return
*/
public Class<? extends ConfigurableComponent>[] value() default {};
/**
* Fully qualified class names you want to link to. Use this when the class
* you want to link to is not in the class path of the component you are
* linking from.
*
* @return
*/
public String[] classNames() default {};
}

View File

@ -24,16 +24,25 @@ import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* <p>
* Marker annotation a {@link org.apache.nifi.processor.Processor Processor},
* {@link org.apache.nifi.controller.ControllerService ControllerService}, or
* {@link org.apache.nifi.reporting.ReportingTask ReportingTask}
* implementation can use to indicate a method
* should be called whenever the component is added to the flow. This method
* will be called once for the entire life of a component instance.
*
* </p>
*
* <p>
* Methods with this annotation are called without any arguments, as all settings
* and properties can be assumed to be the defaults.
* </p>
*
* <p>
* If any method annotated with this annotation throws a Throwable, the component
* will not be added to the flow.
*
* </p>
*
* @author none
*/
@Documented

View File

@ -23,19 +23,32 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.apache.nifi.controller.ConfigurationContext;
/**
* Marker annotation a {@link org.apache.nifi.processor.Processor Processor},
* {@link org.apache.nifi.controller.ControllerService ControllerService} or
* {@link org.apache.nifi.reporting.ReportingTask ReportingTask}
* can use to indicate a method should be called whenever the component is disabled.
* <p>
* Marker annotation a {@link org.apache.nifi.controller.ControllerService ControllerService}
* can use to indicate a method should be called whenever the service is disabled.
*</p>
*
* <p>
* Methods using this annotation must take no arguments. If a method with this annotation
* throws a Throwable, a log message and bulletin will be issued for the component, but
* the component will still be disabled.
* Methods using this annotation are permitted to take zero arguments or to take a single
* argument of type {@link ConfigurationContext}. If a method with this annotation
* throws a Throwable, a log message and bulletin will be issued for the service, and the
* service will remain in a 'DISABLING' state. When this occurs, the method with this annotation
* will be called again after some period of time. This will continue until the method returns
* without throwing any Throwable. Until that time, the service will remain in a 'DISABLING' state
* and cannot be enabled again.
* </p>
*
* <p>
* Note that this annotation will be ignored if applied to a ReportingTask or Processor. For a Controller
* Service, enabling and disabling are considered lifecycle events, as the action makes them usable or
* unusable by other components. However, for a Processor and a Reporting
* Task, these are not lifecycle events but rather a mechanism to allow a component to be excluded when
* starting or stopping a group of components.
* </p>
*
* @author none
*/
@Documented
@Target({ElementType.METHOD})

View File

@ -25,35 +25,35 @@ import java.lang.annotation.Target;
/**
* <p>
* Marker annotation a {@link org.apache.nifi.processor.Processor Processor},
* {@link org.apache.nifi.controller.ControllerService ControllerService} or
* {@link org.apache.nifi.reporting.ReportingTask ReportingTask}
* can use to indicate a method should be called whenever the component is enabled.
* Any method that has this annotation will be called every time a user enables the component.
* Marker annotation a {@link org.apache.nifi.controller.ControllerService ControllerService}
* can use to indicate a method should be called whenever the service is enabled.
* Any method that has this annotation will be called every time a user enables the service.
* Additionally, each time that NiFi is restarted, if NiFi is configured to "auto-resume state"
* and the component is enabled (whether stopped or running), the method will be invoked.
* and the service is enabled, the method will be invoked.
* </p>
*
* <p>
* Methods using this annotation must take either 0 arguments or a single argument.
* </p>
*
* <p>
* If using 1 argument and the component using the annotation is a Processor, that argument must
* be of type {@link org.apache.nifi.processor.ProcessContext ProcessContext}.
* </p>
*
* <p>
* If using 1 argument and the component using the annotation is a Reporting Task or Controller Service,
* that argument must be of type {@link org.apache.nifi.controller.ConfigurationContext ConfigurationContext}.
* Methods using this annotation must take either 0 arguments or a single argument of type
* {@link org.apache.nifi.controller.ConfigurationContext ConfigurationContext}.
* </p>
*
* <p>
* If a method with this annotation throws a Throwable, a log message and bulletin will be issued
* for the component, but the component will still be enabled.
* for the component. In this event, the service will remain in an 'ENABLING' state and will not be
* usable. All methods with this annotation will then be called again after a delay. The service will
* not be made available for use until all methods with this annotation have returned without throwing
* anything.
* </p>
*
* <p>
* Note that this annotation will be ignored if applied to a ReportingTask or Processor. For a Controller
* Service, enabling and disabling are considered lifecycle events, as the action makes them usable or
* unusable by other components. However, for a Processor and a Reporting
* Task, these are not lifecycle events but rather a mechanism to allow a component to be excluded when
* starting or stopping a group of components.
* </p>
*
* @author none
*
*/
@Documented
@Target({ElementType.METHOD})

View File

@ -23,7 +23,11 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.apache.nifi.controller.ConfigurationContext;
import org.apache.nifi.processor.ProcessContext;
/**
* <p>
* Marker annotation a {@link org.apache.nifi.processor.Processor Processor},
* {@link org.apache.nifi.controller.ControllerService ControllerService}, or
* {@link org.apache.nifi.reporting.ReportingTask ReportingTask} implementation
@ -32,7 +36,15 @@ import java.lang.annotation.Target;
* component instance. If the method throw any Throwable, that Throwable will be
* caught and logged but will not prevent subsequent methods with this annotation
* or removal of the component from the flow.
*
* </p>
*
* <p>
* Methods with this annotation are permitted to take no arguments or to take a single
* argument. If using a single argument, that argument must be of type {@link ConfigurationContext}
* if the component is a ReportingTask or a ControllerService. If the component is a Processor,
* then the argument must be of type {@link ProcessContext}.
* </p>
*
* @author none
*/
@Documented

View File

@ -23,7 +23,11 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.apache.nifi.controller.ConfigurationContext;
import org.apache.nifi.processor.ProcessContext;
/**
* <p>
* Marker annotation a {@link org.apache.nifi.processor.Processor Processor},
* {@link org.apache.nifi.controller.ControllerService ControllerService}, or
* {@link org.apache.nifi.reporting.ReportingTask ReportingTask} implementation
@ -31,7 +35,14 @@ import java.lang.annotation.Target;
* This will be called at most once for each component in a JVM lifetime.
* It is not, however, guaranteed that this method will be called on shutdown, as
* the service may be killed suddenly.
*
* </p>
*
* <p>
* Methods with this annotation are permitted to take either 0 or 1 argument. If an argument
* is used, it must be of type {@link ConfigurationContext} if the component is a ReportingTask
* or Controller Service, or of type {@link ProcessContext} if the component is a Processor.
* </p>
*
* @author none
*/
@Documented

View File

@ -23,6 +23,9 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.apache.nifi.controller.ConfigurationContext;
import org.apache.nifi.processor.ProcessContext;
/**
* <p>
* Marker annotation a {@link org.apache.nifi.processor.Processor Processor} or
@ -47,6 +50,12 @@ import java.lang.annotation.Target;
* longer scheduled to run (as opposed to after all threads have returned from the
* <code>onTrigger</code> method), see the {@link OnUnscheduled} annotation.
* </p>
*
* <p>
* Methods with this annotation are permitted to take either 0 or 1 argument. If an argument
* is used, it must be of type {@link ConfigurationContext} if the component is a ReportingTask
* or of type {@link ProcessContext} if the component is a Processor.
* </p>
*
* @author none
*/

View File

@ -47,8 +47,6 @@ import java.lang.annotation.Target;
* If using 1 argument and the component using the annotation is a Reporting Task, that argument must
* be of type {@link org.apache.nifi.controller.ConfigurationContext ConfigurationContext}.
* </p>
*
* @author none
*/
@Documented
@Target({ElementType.METHOD})

View File

@ -187,9 +187,8 @@ public abstract class AbstractConfigurableComponent implements ConfigurableCompo
}
public final List<PropertyDescriptor> getPropertyDescriptors() {
final List<PropertyDescriptor> descriptors = new ArrayList<>();
descriptors.addAll(getSupportedPropertyDescriptors());
return descriptors;
final List<PropertyDescriptor> supported = getSupportedPropertyDescriptors();
return supported == null ? Collections.<PropertyDescriptor>emptyList() :new ArrayList<>(supported);
}
@Override

View File

@ -142,9 +142,19 @@ public final class PropertyDescriptor implements Comparable<PropertyDescriptor>
final Set<String> validIdentifiers = context.getControllerServiceLookup().getControllerServiceIdentifiers(controllerServiceDefinition);
if (validIdentifiers != null && validIdentifiers.contains(input)) {
final ControllerService controllerService = context.getControllerServiceLookup().getControllerService(input);
if (!context.getControllerServiceLookup().isControllerServiceEnabled(controllerService)) {
if ( !context.isValidationRequired(controllerService) ) {
return new ValidationResult.Builder()
.input(input)
.input(input)
.subject(getName())
.valid(true)
.build();
}
final String serviceId = controllerService.getIdentifier();
if (!context.getControllerServiceLookup().isControllerServiceEnabled(serviceId) &&
!context.getControllerServiceLookup().isControllerServiceEnabling(serviceId)) {
return new ValidationResult.Builder()
.input(context.getControllerServiceLookup().getControllerServiceName(serviceId))
.subject(getName())
.valid(false)
.explanation("Controller Service " + controllerService + " is disabled")

View File

@ -79,4 +79,32 @@ public interface ValidationContext {
* @return
*/
String getAnnotationData();
/**
* There are times when the framework needs to consider a component valid, even if it
* references an invalid ControllerService. This method will return <code>false</code>
* if the component is to be considered valid even if the given Controller Service is referenced
* and is invalid.
* @param service
*/
boolean isValidationRequired(ControllerService service);
/**
* Returns <code>true</code> if the given value contains a NiFi Expression Language expression,
* <code>false</code> if it does not
*
* @param value
* @return
*/
boolean isExpressionLanguagePresent(String value);
/**
* Returns <code>true</code> if the property with the given name supports the NiFi Expression Language,
* <code>false</code> if the property does not support the Expression Language or is not a valid property
* name
*
* @param propertyName
* @return
*/
boolean isExpressionLanguageSupported(String propertyName);
}

View File

@ -22,6 +22,7 @@ import org.apache.nifi.components.AbstractConfigurableComponent;
import org.apache.nifi.components.PropertyDescriptor;
import org.apache.nifi.components.PropertyValue;
import org.apache.nifi.controller.annotation.OnConfigured;
import org.apache.nifi.logging.ComponentLog;
import org.apache.nifi.processor.ProcessorInitializationContext;
import org.apache.nifi.reporting.InitializationException;
@ -30,11 +31,13 @@ public abstract class AbstractControllerService extends AbstractConfigurableComp
private String identifier;
private ControllerServiceLookup serviceLookup;
private volatile ConfigurationContext configContext;
private ComponentLog logger;
@Override
public final void initialize(final ControllerServiceInitializationContext context) throws InitializationException {
this.identifier = context.getIdentifier();
serviceLookup = context.getControllerServiceLookup();
logger = context.getLogger();
init(context);
}
@ -88,4 +91,12 @@ public abstract class AbstractControllerService extends AbstractConfigurableComp
*/
protected void init(final ControllerServiceInitializationContext config) throws InitializationException {
}
/**
* Returns the logger that has been provided to the component by the framework in its initialize method.
* @return
*/
protected ComponentLog getLogger() {
return logger;
}
}

View File

@ -16,6 +16,8 @@
*/
package org.apache.nifi.controller;
import org.apache.nifi.logging.ComponentLog;
public interface ControllerServiceInitializationContext {
/**
@ -33,4 +35,12 @@ public interface ControllerServiceInitializationContext {
* @return
*/
ControllerServiceLookup getControllerServiceLookup();
/**
* Returns a logger that can be used to log important events in a standard way and generate
* bulletins when appropriate
*
* @return
*/
ComponentLog getLogger();
}

View File

@ -41,6 +41,18 @@ public interface ControllerServiceLookup {
*/
boolean isControllerServiceEnabled(String serviceIdentifier);
/**
* Returns <code>true</code> if the Controller Service with the given
* identifier has been enabled but is still in the transitioning state,
* otherwise returns <code>false</code>.
* If the given identifier is not known by this ControllerServiceLookup,
* returns <code>false</code>.
*
* @param serviceIdentifier
* @return
*/
boolean isControllerServiceEnabling(String serviceIdentifier);
/**
* Returns <code>true</code> if the given Controller Service is enabled,
* <code>false</code> otherwise. If the given Controller Service is not
@ -63,4 +75,11 @@ public interface ControllerServiceLookup {
*/
Set<String> getControllerServiceIdentifiers(Class<? extends ControllerService> serviceType) throws IllegalArgumentException;
/**
* Returns the name of the Controller service with the given identifier. If no service can be
* found with this identifier, returns {@code null}.
* @param serviceIdentifier
* @return
*/
String getControllerServiceName(String serviceIdentifier);
}

View File

@ -0,0 +1,100 @@
/*
* 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.nifi.logging;
/**
* <p>
* The ComponentLog provides a mechanism to ensure that all NiFi components are logging and reporting
* information in a consistent way. When messages are logged to the ComponentLog, each message has the
* following characteristics:
* </p>
*
* <ul>
* <li>
* The <code>toString()</code> of the component is automatically prepended to the message so that it is clear
* which component is providing the information. This is important, since a single component may have many
* different instances within the same NiFi instance.
* </li>
* <li>
* If the last value in an Object[] argument that is passed to the logger is a Throwable, then the logged message
* will include a <code>toString()</code> of the Throwable; in addition, if the component's logger is set to
* DEBUG level via the logback configuration, the Stacktrace will also be logged. This provides a mechanism to easily
* enable stacktraces in the logs when they are desired without filling the logs with unneeded stack traces for messages
* that end up occurring often.
* </li>
* <li>
* Any message that is logged with a Severity level that meets or exceeds the configured Bulletin Level for that component
* will also cause a Bulletin to be generated, so that the message is visible in the UI, allowing Dataflow Managers
* to understand that a problem exists and what the issue is.
* </li>
* </ul>
*
*/
public interface ComponentLog {
void warn(String msg, Throwable t);
void warn(String msg, Object[] os);
void warn(String msg, Object[] os, Throwable t);
void warn(String msg);
void trace(String msg, Throwable t);
void trace(String msg, Object[] os);
void trace(String msg);
void trace(String msg, Object[] os, Throwable t);
boolean isWarnEnabled();
boolean isTraceEnabled();
boolean isInfoEnabled();
boolean isErrorEnabled();
boolean isDebugEnabled();
void info(String msg, Throwable t);
void info(String msg, Object[] os);
void info(String msg);
void info(String msg, Object[] os, Throwable t);
String getName();
void error(String msg, Throwable t);
void error(String msg, Object[] os);
void error(String msg);
void error(String msg, Object[] os, Throwable t);
void debug(String msg, Throwable t);
void debug(String msg, Object[] os);
void debug(String msg, Object[] os, Throwable t);
void debug(String msg);
}

View File

@ -16,58 +16,15 @@
*/
package org.apache.nifi.logging;
public interface ProcessorLog {
void warn(String msg, Throwable t);
void warn(String msg, Object[] os);
void warn(String msg, Object[] os, Throwable t);
void warn(String msg);
void trace(String msg, Throwable t);
void trace(String msg, Object[] os);
void trace(String msg);
void trace(String msg, Object[] os, Throwable t);
boolean isWarnEnabled();
boolean isTraceEnabled();
boolean isInfoEnabled();
boolean isErrorEnabled();
boolean isDebugEnabled();
void info(String msg, Throwable t);
void info(String msg, Object[] os);
void info(String msg);
void info(String msg, Object[] os, Throwable t);
String getName();
void error(String msg, Throwable t);
void error(String msg, Object[] os);
void error(String msg);
void error(String msg, Object[] os, Throwable t);
void debug(String msg, Throwable t);
void debug(String msg, Object[] os);
void debug(String msg, Object[] os, Throwable t);
void debug(String msg);
/**
* The ProcessorLog is an extension of ComponentLog but provides no additional functionality.
* It exists because ProcessorLog was created first,
* but when Controller Services and Reporting Tasks began to be used more heavily loggers
* were needed for them as well. We did not want to return a ProcessorLog to a ControllerService
* or a ReportingTask, so all of the methods were moved to a higher interface named ComponentLog.
* However, we kept the ProcessorLog interface around in order to maintain backward compatibility.
*/
public interface ProcessorLog extends ComponentLog {
}

View File

@ -484,6 +484,9 @@ public interface ProcessSession {
/**
* Executes the given callback against the contents corresponding to the
* given FlowFile.
*
* <i>Note</i>: The OutputStream provided to the given OutputStreamCallback
* will not be accessible once this method has completed its execution.
*
* @param source
* @param reader
@ -498,9 +501,11 @@ public interface ProcessSession {
* destroyed, and the session is automatically rolled back and what is left
* of the FlowFile is destroyed.
* @throws FlowFileAccessException if some IO problem occurs accessing
* FlowFile content
* FlowFile content; if an attempt is made to access the InputStream
* provided to the given InputStreamCallback after this method completed its
* execution
*/
void read(FlowFile source, InputStreamCallback reader);
void read(FlowFile source, InputStreamCallback reader) throws FlowFileAccessException;
/**
* Combines the content of all given source FlowFiles into a single given
@ -560,7 +565,10 @@ public interface ProcessSession {
/**
* Executes the given callback against the content corresponding to the
* given FlowFile
* given FlowFile.
*
* <i>Note</i>: The OutputStream provided to the given OutputStreamCallback
* will not be accessible once this method has completed its execution.
*
* @param source
* @param writer
@ -576,13 +584,19 @@ public interface ProcessSession {
* destroyed, and the session is automatically rolled back and what is left
* of the FlowFile is destroyed.
* @throws FlowFileAccessException if some IO problem occurs accessing
* FlowFile content
* FlowFile content; if an attempt is made to access the OutputStream
* provided to the given OutputStreamCallaback after this method completed
* its execution
*/
FlowFile write(FlowFile source, OutputStreamCallback writer);
FlowFile write(FlowFile source, OutputStreamCallback writer) throws FlowFileAccessException;
/**
* Executes the given callback against the content corresponding to the
* given flow file
* given flow file.
*
* <i>Note</i>: The InputStream & OutputStream provided to the given
* StreamCallback will not be accessible once this method has completed its
* execution.
*
* @param source
* @param writer
@ -598,20 +612,28 @@ public interface ProcessSession {
* destroyed, and the session is automatically rolled back and what is left
* of the FlowFile is destroyed.
* @throws FlowFileAccessException if some IO problem occurs accessing
* FlowFile content
* FlowFile content; if an attempt is made to access the InputStream or
* OutputStream provided to the given StreamCallback after this method
* completed its execution
*/
FlowFile write(FlowFile source, StreamCallback writer);
FlowFile write(FlowFile source, StreamCallback writer) throws FlowFileAccessException;
/**
* Executes the given callback against the content corresponding to the
* given FlowFile, such that any data written to the OutputStream of the
* content will be appended to the end of FlowFile.
*
* <i>Note</i>: The OutputStream provided to the given OutputStreamCallback
* will not be accessible once this method has completed its execution.
*
* @param source
* @param writer
* @return
* @throws FlowFileAccessException if an attempt is made to access the
* OutputStream provided to the given OutputStreamCallaback after this method
* completed its execution
*/
FlowFile append(FlowFile source, OutputStreamCallback writer);
FlowFile append(FlowFile source, OutputStreamCallback writer) throws FlowFileAccessException;
/**
* Writes to the given FlowFile all content from the given content path.

View File

@ -20,6 +20,7 @@ import java.util.concurrent.TimeUnit;
import org.apache.nifi.components.AbstractConfigurableComponent;
import org.apache.nifi.controller.ControllerServiceLookup;
import org.apache.nifi.logging.ComponentLog;
import org.apache.nifi.processor.ProcessorInitializationContext;
public abstract class AbstractReportingTask extends AbstractConfigurableComponent implements ReportingTask {
@ -28,10 +29,12 @@ public abstract class AbstractReportingTask extends AbstractConfigurableComponen
private String name;
private long schedulingNanos;
private ControllerServiceLookup serviceLookup;
private ComponentLog logger;
@Override
public final void initialize(final ReportingInitializationContext config) throws InitializationException {
identifier = config.getIdentifier();
logger = config.getLogger();
name = config.getName();
schedulingNanos = config.getSchedulingPeriod(TimeUnit.NANOSECONDS);
serviceLookup = config.getControllerServiceLookup();
@ -91,4 +94,11 @@ public abstract class AbstractReportingTask extends AbstractConfigurableComponen
protected void init(final ReportingInitializationContext config) throws InitializationException {
}
/**
* Returns the logger that has been provided to the component by the framework in its initialize method.
* @return
*/
protected ComponentLog getLogger() {
return logger;
}
}

View File

@ -19,6 +19,7 @@ package org.apache.nifi.reporting;
import java.util.concurrent.TimeUnit;
import org.apache.nifi.controller.ControllerServiceLookup;
import org.apache.nifi.logging.ComponentLog;
import org.apache.nifi.scheduling.SchedulingStrategy;
/**
@ -77,4 +78,13 @@ public interface ReportingInitializationContext {
* @return
*/
SchedulingStrategy getSchedulingStrategy();
/**
* Returns a logger that can be used to log important events in a standard way and generate
* bulletins when appropriate
*
* @return
*/
ComponentLog getLogger();
}

View File

@ -17,6 +17,7 @@
package org.apache.nifi.web;
/**
* An general error occurred when attempting to communicate with the cluster.
*/
public class ClusterRequestException extends RuntimeException {

View File

@ -0,0 +1,157 @@
/*
* 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.nifi.web;
import java.util.Collection;
import java.util.Map;
/**
* Details about a given component. Contains configuration and current validation errors.
*/
public class ComponentDetails {
private final String id;
private final String name;
private final String type;
private final String state;
private final String annotationData;
private final Map<String, String> properties;
private final Collection<String> validationErrors;
private ComponentDetails(final Builder builder) {
this.id = builder.id;
this.name = builder.name;
this.type = builder.type;
this.state = builder.state;
this.annotationData = builder.annotationData;
this.properties = builder.properties;
this.validationErrors = builder.validationErrors;
}
/**
* The component id.
*
* @return
*/
public String getId() {
return id;
}
/**
* The component name.
*
* @return
*/
public String getName() {
return name;
}
/**
* The component type.
*
* @return
*/
public String getType() {
return type;
}
/**
* The component state.
*
* @return
*/
public String getState() {
return state;
}
/**
* The component's annotation data.
*
* @return
*/
public String getAnnotationData() {
return annotationData;
}
/**
* Mapping of component properties.
*
* @return
*/
public Map<String, String> getProperties() {
return properties;
}
/**
* Current validation errors for the component.
*
* @return
*/
public Collection<String> getValidationErrors() {
return validationErrors;
}
public static final class Builder {
private String id;
private String name;
private String type;
private String state;
private String annotationData;
private Map<String, String> properties;
private Collection<String> validationErrors;
public Builder id(final String id) {
this.id = id;
return this;
}
public Builder name(final String name) {
this.name = name;
return this;
}
public Builder type(final String type) {
this.type = type;
return this;
}
public Builder state(final String state) {
this.state = state;
return this;
}
public Builder annotationData(final String annotationData) {
this.annotationData = annotationData;
return this;
}
public Builder properties(final Map<String, String> properties) {
this.properties = properties;
return this;
}
public Builder validateErrors(final Collection<String> validationErrors) {
this.validationErrors = validationErrors;
return this;
}
public ComponentDetails build() {
return new ComponentDetails(this);
}
}
}

View File

@ -0,0 +1,137 @@
/*
* 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.nifi.web;
/**
* An action that represents the configuration of a component.
*/
public class ConfigurationAction {
private final String id;
private final String name;
private final String type;
private final String field;
private final String previousValue;
private final String value;
private ConfigurationAction(final Builder builder) {
this.id = builder.id;
this.name = builder.name;
this.type = builder.type;
this.field = builder.field;
this.previousValue = builder.previousValue;
this.value = builder.value;
}
/**
* The id of the component being modified.
*
* @return
*/
public String getId() {
return id;
}
/**
* The name of the component being modified.
*
* @return
*/
public String getName() {
return name;
}
/**
* The type of the component being modified.
*
* @return
*/
public String getType() {
return type;
}
/**
* Gets the name of the field, property, etc that has been modified.
*
* @return
*/
public String getField() {
return field;
}
/**
* Gets the previous value.
*
* @return
*/
public String getPreviousValue() {
return previousValue;
}
/**
* Gets the new value.
*
* @return
*/
public String getValue() {
return value;
}
public static class Builder {
private String id;
private String name;
private String type;
private String field;
private String previousValue;
private String value;
public Builder id(final String id) {
this.id = id;
return this;
}
public Builder name(final String name) {
this.name = name;
return this;
}
public Builder type(final String type) {
this.type = type;
return this;
}
public Builder field(final String field) {
this.field = field;
return this;
}
public Builder previousValue(final String previousValue) {
this.previousValue = previousValue;
return this;
}
public Builder value(final String value) {
this.value = value;
return this;
}
public ConfigurationAction build() {
return new ConfigurationAction(this);
}
}
}

View File

@ -0,0 +1,102 @@
/*
* 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.nifi.web;
import java.util.Collection;
import org.apache.nifi.controller.ControllerService;
/**
* NiFi web context providing limited access to dataflow configuration for
* component custom UIs.
*/
public interface NiFiWebConfigurationContext {
/**
* Gets the ControllerService for the specified identifier. If a
* corresponding service cannot be found, null is returned. If this NiFi is
* clustered, the only services available will be those those
* availability is NCM only.
*
* @param serviceIdentifier
* @return
*/
ControllerService getControllerService(String serviceIdentifier);
/**
* Provides a mechanism for custom UIs to save actions to appear in NiFi
* configuration history. Note all fields within each Action must be
* populated. Null values will result in a failure to insert the audit
* record. Since the saving to these actions is separate from the actual
* configuration change, a failure to insert here will just generate a
* warning log message. The recording of these actions typically happens
* after a configuration change is applied. Since those changes have already
* been applied to the flow, we cannot revert them because of a failure to
* insert an audit record.
*
* @param requestContext
* @param actions
* @throws IllegalArgumentException When the requestContext isn't fully populated or
* isn't appropriate for the given request
*/
void saveActions(NiFiWebRequestContext requestContext, Collection<ConfigurationAction> actions);
/**
* Gets the current user dn. Returns null if no user is found.
*
* @return
*/
String getCurrentUserDn();
/**
* Gets the current user name. Returns null if no user is found.
*
* @return
*/
String getCurrentUserName();
/**
* Sets the annotation data for the underlying component.
*
* @param configurationContext
* @param annotationData
* @return the configuration for the underlying component
* @throws ResourceNotFoundException if the underlying component does not exit
* @throws InvalidRevisionException if a revision other than the current
* revision is given
* @throws ClusterRequestException if the annotation data was unable to be
* set for the underlying component. This exception will only be thrown when operating
* in a cluster.
* @throws IllegalArgumentException When the requestContext isn't fully populated or
* isn't appropriate for the given request
*/
ComponentDetails setAnnotationData(NiFiWebConfigurationRequestContext configurationContext, String annotationData) throws ResourceNotFoundException, InvalidRevisionException, ClusterRequestException;
/**
* Gets the details for the underlying component (including configuration, validation errors, and annotation data).
*
* @param requestContext
* @return the configuration for the underlying component
* @throws ResourceNotFoundException if the underlying component does not exit
* @throws ClusterRequestException if the underlying component was unable to be
* retrieved from the cluster. This exception will only be thrown when
* operating in a cluster.
* @throws IllegalArgumentException When the requestContext isn't fully populated or
* isn't appropriate for the given request
*/
ComponentDetails getComponentDetails(NiFiWebRequestContext requestContext) throws ResourceNotFoundException, ClusterRequestException;
}

View File

@ -0,0 +1,31 @@
/*
* 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.nifi.web;
/**
* Contextual details required to make a configuration request from a UI extension.
*/
public interface NiFiWebConfigurationRequestContext extends NiFiWebRequestContext {
/**
* The revision to include in the request.
*
* @return the revision
*/
Revision getRevision();
}

View File

@ -24,6 +24,7 @@ import org.apache.nifi.controller.ControllerService;
* NiFi web context providing limited access to dataflow configuration for
* processor custom UIs.
*/
@Deprecated
public interface NiFiWebContext {
/**

View File

@ -19,6 +19,7 @@ package org.apache.nifi.web;
/**
* Context configuration for methods invoked from the NiFiWebContext.
*/
@Deprecated
public interface NiFiWebContextConfig {
/**

View File

@ -0,0 +1,58 @@
/*
* 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.nifi.web;
/**
* Contextual details required to make a request from a UI extension.
*/
public interface NiFiWebRequestContext {
/**
* Returns the type of UI extension is making the request.
*
* @return
*/
UiExtensionType getExtensionType();
/**
* The request protocol scheme (http or https). When scheme is https, the
* X509Certificate can be used for subsequent remote requests.
*
* @return the protocol scheme
*/
String getScheme();
/**
* The id of the component.
*
* @return the ID
*/
String getId();
/**
* Returns the proxied entities chain. The format of the chain is as
* follows:
*
* <code>
* &lt;CN=original-proxied-entity&gt;&lt;CN=first-proxy&gt;&lt;CN=second-proxy&gt;...
* </code>
*
* @return the proxied entities chain or null if no chain
*/
String getProxiedEntitiesChain();
}

View File

@ -19,6 +19,7 @@ package org.apache.nifi.web;
/**
*
*/
@Deprecated
public class ProcessorConfigurationAction {
private final String processorId;

View File

@ -22,6 +22,7 @@ import java.util.Map;
/**
*
*/
@Deprecated
public class ProcessorInfo {
private final String id;

View File

@ -37,12 +37,12 @@ public class Revision implements Serializable {
* the client ID
*/
private final String clientId;
public Revision(Long revision, String clientId) {
this.version = revision;
this.clientId = clientId;
}
public String getClientId() {
return clientId;
}
@ -51,34 +51,6 @@ public class Revision implements Serializable {
return version;
}
/**
* A factory method for creating a new Revision instance whose version is
* this instance's version plus 1.
*
* @return an updated revision
*/
public Revision increment() {
final long incrementedVersion;
if (version == null) {
incrementedVersion = 0;
} else {
incrementedVersion = version + 1;
}
return new Revision(incrementedVersion, clientId);
}
/**
* A factory method for creating a new Revision instance whose version is
* this instance's version plus 1 and whose client ID is the given client
* ID.
*
* @param clientId the client ID
* @return an updated revision
*/
public Revision increment(String clientId) {
return new Revision(increment().getVersion(), clientId);
}
@Override
public boolean equals(final Object obj) {

View File

@ -0,0 +1,31 @@
/*
* 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.nifi.web;
/**
* Types of UI extensions. Since a UI extension could support multiple
* types of custom UIs it will need to include the type so the framework
* can appropriate understand and process the request (recording actions
* in the audit database, replicating a request throughout the cluster to
* the appropriate endpoints, etc).
*/
public enum UiExtensionType {
ContentViewer,
ProcessorConfiguration,
ControllerServiceConfiguration,
ReportingTaskConfiguration
}

View File

@ -0,0 +1,74 @@
/*
* 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.nifi.web;
import java.io.IOException;
import java.io.InputStream;
/**
* Interface for obtaining content from the NiFi content repository.
*/
public interface ViewableContent {
public static final String CONTENT_REQUEST_ATTRIBUTE = "org.apache.nifi.web.content";
public enum DisplayMode {
Original,
Formatted,
Hex;
}
/**
* The stream to the viewable content. The data stream can only be read once so
* an extension can call this method or getContent.
*
* @return
*/
InputStream getContentStream();
/**
* Gets the content as a string. The data stream can only be read once so
* an extension can call this method or getContentStream.
*
* @return
* @throws java.io.IOException
*/
String getContent() throws IOException;
/**
* Returns the desired play mode. If the mode is Hex the
* framework will handle generating the mark up. The only
* values that an extension will see is Original or Formatted.
*
* @return
*/
DisplayMode getDisplayMode();
/**
* The contents file name.
*
* @return
*/
String getFileName();
/**
* The mime type of the content.
*
* @return
*/
String getContentType();
}

View File

@ -181,6 +181,11 @@ The following binary components are provided under the Apache Software License v
Apache log4j
Copyright 2007 The Apache Software Foundation
(ASLv2) Apache Tika
The following NOTICE information applies:
Apache Tika Core
Copyright 2007-2015 The Apache Software Foundation
(ASLv2) Apache Commons Configuration
The following NOTICE information applies:
Apache Commons Configuration
@ -496,6 +501,39 @@ The following binary components are provided under the Apache Software License v
Apache License Version 2.0 http://www.apache.org/licenses/.
(c) Daniel Lemire, http://lemire.me/en/
(ASLv2) Twitter4J
The following NOTICE information applies:
Copyright 2007 Yusuke Yamamoto
Twitter4J includes software from JSON.org to parse JSON response from the Twitter API. You can see the license term at http://www.JSON.org/license.html
(ASLv2) JOAuth
The following NOTICE information applies:
JOAuth
Copyright 2010-2013 Twitter, Inc
Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0
(ASLv2) Hosebird Client
The following NOTICE information applies:
Hosebird Client (hbc)
Copyright 2013 Twitter, Inc.
Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0
(ASLv2) GeoIP2 Java API
The following NOTICE information applies:
GeoIP2 Java API
This software is Copyright (c) 2013 by MaxMind, Inc.
This is free software, licensed under the Apache License, Version 2.0.
(ASLv2) Google HTTP Client Library for Java
The following NOTICE information applies:
Google HTTP Client Library for Java
This is free software, licensed under the Apache License, Version 2.0.
(ASLv2) Amazon Web Services SDK
The following NOTICE information applies:
Copyright 2010-2014 Amazon.com, Inc. or its affiliates. All Rights Reserved.
@ -550,6 +588,14 @@ The following binary components are provided under the Common Development and Di
(CDDL 1.0) JavaServer Pages(TM) API (javax.servlet.jsp:jsp-api:jar:2.1 - http://jsp.java.net)
(CDDL 1.0) SR 250 Common Annotations For The JavaTM Platform (javax.annotation:jsr250-api:jar:1.0 - http://jcp.org/aboutJava/communityprocess/final/jsr250/index.html)
************************
Creative Commons Attribution-ShareAlike 3.0
************************
The following binary components are provided under the Creative Commons Attribution-ShareAlike 3.0. See project link for details.
(CCAS 3.0) MaxMind DB (https://github.com/maxmind/MaxMind-DB)
************************
Eclipse Public License 1.0
************************
@ -569,6 +615,15 @@ The following binary components are provided under the Mozilla Public License v2
(MPL 2.0) Saxon HE (net.sf.saxon:Saxon-HE:jar:9.6.0-4 - http://www.saxonica.com/)
*****************
Mozilla Public License v1.1
*****************
The following binary components are provided under the Mozilla Public License v1.1. See project link for details.
(MPL 1.1) HAPI Base (ca.uhn.hapi:hapi-base:2.2 - http://hl7api.sourceforge.net/)
(MPL 1.1) HAPI Structures (ca.uhn.hapi:hapi-structures-v*:2.2 - http://hl7api.sourceforge.net/)
*****************
Public Domain
*****************

View File

@ -1,460 +1,484 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
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.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi</artifactId>
<version>0.0.2-incubating-SNAPSHOT</version>
</parent>
<artifactId>nifi-assembly</artifactId>
<packaging>pom</packaging>
<description>This is the assembly Apache NiFi (incubating)</description>
<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<finalName>nifi-${project.version}</finalName>
<attach>false</attach>
</configuration>
<executions>
<execution>
<id>make shared resource</id>
<goals>
<goal>single</goal>
</goals>
<phase>package</phase>
<configuration>
<descriptors>
<descriptor>src/main/assembly/dependencies.xml</descriptor>
</descriptors>
<tarLongFileMode>posix</tarLongFileMode>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jul-to-slf4j</artifactId>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>log4j-over-slf4j</artifactId>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-api</artifactId>
</dependency>
<dependency>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-runtime</artifactId>
</dependency>
<dependency>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-bootstrap</artifactId>
</dependency>
<dependency>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-resources</artifactId>
<classifier>resources</classifier>
<scope>runtime</scope>
<type>zip</type>
</dependency>
<dependency>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-docs</artifactId>
<classifier>resources</classifier>
<scope>runtime</scope>
<type>zip</type>
</dependency>
<dependency>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-framework-nar</artifactId>
<type>nar</type>
</dependency>
<dependency>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-provenance-repository-nar</artifactId>
<type>nar</type>
</dependency>
<dependency>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-standard-services-api-nar</artifactId>
<type>nar</type>
</dependency>
<dependency>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-ssl-context-service-nar</artifactId>
<type>nar</type>
</dependency>
<dependency>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-distributed-cache-services-nar</artifactId>
<type>nar</type>
</dependency>
<dependency>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-standard-nar</artifactId>
<type>nar</type>
</dependency>
<dependency>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-jetty-bundle</artifactId>
<type>nar</type>
</dependency>
<dependency>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-update-attribute-nar</artifactId>
<type>nar</type>
</dependency>
<dependency>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-hadoop-libraries-nar</artifactId>
<type>nar</type>
</dependency>
<dependency>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-hadoop-nar</artifactId>
<type>nar</type>
</dependency>
<dependency>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-kafka-nar</artifactId>
<type>nar</type>
</dependency>
<!-- 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. -->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi</artifactId>
<version>0.1.0-incubating-SNAPSHOT</version>
</parent>
<artifactId>nifi-assembly</artifactId>
<packaging>pom</packaging>
<description>This is the assembly Apache NiFi (incubating)</description>
<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<finalName>nifi-${project.version}</finalName>
<attach>false</attach>
</configuration>
<executions>
<execution>
<id>make shared resource</id>
<goals>
<goal>single</goal>
</goals>
<phase>package</phase>
<configuration>
<descriptors>
<descriptor>src/main/assembly/dependencies.xml</descriptor>
</descriptors>
<tarLongFileMode>posix</tarLongFileMode>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-http-context-map-nar</artifactId>
<type>nar</type>
</dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-kite-nar</artifactId>
<type>nar</type>
</dependency>
</dependencies>
<properties>
<!--Wrapper Properties-->
<nifi.wrapper.jvm.heap.initial.mb>256</nifi.wrapper.jvm.heap.initial.mb>
<nifi.wrapper.jvm.heap.max.mb>512</nifi.wrapper.jvm.heap.max.mb>
<nifi.initial.permgen.size.mb>128</nifi.initial.permgen.size.mb>
<nifi.max.permgen.size.mb>128</nifi.max.permgen.size.mb>
<nifi.wrapper.logfile.maxsize>10m</nifi.wrapper.logfile.maxsize>
<nifi.wrapper.logfile.maxfiles>10</nifi.wrapper.logfile.maxfiles>
<!-- nifi.properties: core properties -->
<nifi.version>${project.version}</nifi.version>
<nifi.flowcontroller.autoResumeState>true</nifi.flowcontroller.autoResumeState>
<nifi.flowcontroller.graceful.shutdown.period>10 sec</nifi.flowcontroller.graceful.shutdown.period>
<nifi.flowservice.writedelay.interval>500 ms</nifi.flowservice.writedelay.interval>
<nifi.administrative.yield.duration>30 sec</nifi.administrative.yield.duration>
<nifi.bored.yield.duration>10 millis</nifi.bored.yield.duration>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jul-to-slf4j</artifactId>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>log4j-over-slf4j</artifactId>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-api</artifactId>
</dependency>
<dependency>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-runtime</artifactId>
</dependency>
<dependency>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-bootstrap</artifactId>
</dependency>
<dependency>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-resources</artifactId>
<classifier>resources</classifier>
<scope>runtime</scope>
<type>zip</type>
</dependency>
<dependency>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-docs</artifactId>
<classifier>resources</classifier>
<scope>runtime</scope>
<type>zip</type>
</dependency>
<dependency>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-framework-nar</artifactId>
<type>nar</type>
</dependency>
<dependency>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-provenance-repository-nar</artifactId>
<type>nar</type>
</dependency>
<dependency>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-standard-services-api-nar</artifactId>
<type>nar</type>
</dependency>
<dependency>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-ssl-context-service-nar</artifactId>
<type>nar</type>
</dependency>
<dependency>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-distributed-cache-services-nar</artifactId>
<type>nar</type>
</dependency>
<dependency>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-standard-nar</artifactId>
<type>nar</type>
</dependency>
<dependency>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-jetty-bundle</artifactId>
<type>nar</type>
</dependency>
<dependency>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-update-attribute-nar</artifactId>
<type>nar</type>
</dependency>
<dependency>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-hadoop-libraries-nar</artifactId>
<type>nar</type>
</dependency>
<dependency>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-hadoop-nar</artifactId>
<type>nar</type>
</dependency>
<dependency>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-kafka-nar</artifactId>
<type>nar</type>
</dependency>
<dependency>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-http-context-map-nar</artifactId>
<type>nar</type>
</dependency>
<dependency>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-kite-nar</artifactId>
<type>nar</type>
</dependency>
<dependency>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-social-media-nar</artifactId>
<version>0.1.0-incubating-SNAPSHOT</version>
<type>nar</type>
</dependency>
<dependency>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-hl7-nar</artifactId>
<version>0.1.0-incubating-SNAPSHOT</version>
<type>nar</type>
</dependency>
<dependency>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-language-translation-nar</artifactId>
<version>0.1.0-incubating-SNAPSHOT</version>
<type>nar</type>
</dependency>
<dependency>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-geo-nar</artifactId>
<version>0.1.0-incubating-SNAPSHOT</version>
<type>nar</type>
</dependency>
</dependencies>
<nifi.flow.configuration.file>./conf/flow.xml.gz</nifi.flow.configuration.file>
<nifi.flow.configuration.archive.dir>./conf/archive/</nifi.flow.configuration.archive.dir>
<nifi.reporting.task.configuration.file>./conf/reporting-tasks.xml</nifi.reporting.task.configuration.file>
<nifi.controller.service.configuration.file>./conf/controller-services.xml</nifi.controller.service.configuration.file>
<nifi.authority.provider.configuration.file>./conf/authority-providers.xml</nifi.authority.provider.configuration.file>
<nifi.templates.directory>./conf/templates</nifi.templates.directory>
<nifi.database.directory>./database_repository</nifi.database.directory>
<properties>
<!--Wrapper Properties -->
<nifi.wrapper.jvm.heap.initial.mb>256</nifi.wrapper.jvm.heap.initial.mb>
<nifi.wrapper.jvm.heap.max.mb>512</nifi.wrapper.jvm.heap.max.mb>
<nifi.initial.permgen.size.mb>128</nifi.initial.permgen.size.mb>
<nifi.max.permgen.size.mb>128</nifi.max.permgen.size.mb>
<nifi.wrapper.logfile.maxsize>10m</nifi.wrapper.logfile.maxsize>
<nifi.wrapper.logfile.maxfiles>10</nifi.wrapper.logfile.maxfiles>
<nifi.flowfile.repository.implementation>org.apache.nifi.controller.repository.WriteAheadFlowFileRepository</nifi.flowfile.repository.implementation>
<nifi.flowfile.repository.directory>./flowfile_repository</nifi.flowfile.repository.directory>
<nifi.flowfile.repository.partitions>256</nifi.flowfile.repository.partitions>
<nifi.flowfile.repository.checkpoint.interval>2 mins</nifi.flowfile.repository.checkpoint.interval>
<nifi.flowfile.repository.always.sync>false</nifi.flowfile.repository.always.sync>
<nifi.swap.manager.implementation>org.apache.nifi.controller.FileSystemSwapManager</nifi.swap.manager.implementation>
<nifi.queue.swap.threshold>20000</nifi.queue.swap.threshold>
<nifi.swap.in.period>5 sec</nifi.swap.in.period>
<nifi.swap.in.threads>1</nifi.swap.in.threads>
<nifi.swap.out.period>5 sec</nifi.swap.out.period>
<nifi.swap.out.threads>4</nifi.swap.out.threads>
<nifi.content.repository.implementation>org.apache.nifi.controller.repository.FileSystemRepository</nifi.content.repository.implementation>
<nifi.content.claim.max.appendable.size>10 MB</nifi.content.claim.max.appendable.size>
<nifi.content.claim.max.flow.files>100</nifi.content.claim.max.flow.files>
<nifi.content.repository.directory.default>./content_repository</nifi.content.repository.directory.default>
<nifi.content.repository.archive.max.retention.period />
<nifi.content.repository.archive.max.usage.percentage />
<nifi.content.repository.archive.enabled>false</nifi.content.repository.archive.enabled>
<nifi.content.repository.always.sync>false</nifi.content.repository.always.sync>
<nifi.content.viewer.url />
<nifi.restore.directory />
<nifi.ui.banner.text />
<nifi.ui.autorefresh.interval>30 sec</nifi.ui.autorefresh.interval>
<nifi.nar.library.directory>./lib</nifi.nar.library.directory>
<nifi.nar.working.directory>./work/nar/</nifi.nar.working.directory>
<nifi.documentation.working.directory>./work/docs/components</nifi.documentation.working.directory>
<nifi.sensitive.props.algorithm>PBEWITHMD5AND256BITAES-CBC-OPENSSL</nifi.sensitive.props.algorithm>
<nifi.sensitive.props.provider>BC</nifi.sensitive.props.provider>
<nifi.h2.url.append>;LOCK_TIMEOUT=25000;WRITE_DELAY=0;AUTO_SERVER=FALSE</nifi.h2.url.append>
<!-- nifi.properties: core properties -->
<nifi.version>${project.version}</nifi.version>
<nifi.flowcontroller.autoResumeState>true</nifi.flowcontroller.autoResumeState>
<nifi.flowcontroller.graceful.shutdown.period>10 sec</nifi.flowcontroller.graceful.shutdown.period>
<nifi.flowservice.writedelay.interval>500 ms</nifi.flowservice.writedelay.interval>
<nifi.administrative.yield.duration>30 sec</nifi.administrative.yield.duration>
<nifi.bored.yield.duration>10 millis</nifi.bored.yield.duration>
<nifi.remote.input.socket.port>9990</nifi.remote.input.socket.port>
<!-- persistent provenance repository properties -->
<nifi.provenance.repository.implementation>org.apache.nifi.provenance.PersistentProvenanceRepository</nifi.provenance.repository.implementation>
<nifi.provenance.repository.directory.default>./provenance_repository</nifi.provenance.repository.directory.default>
<nifi.provenance.repository.max.storage.time>24 hours</nifi.provenance.repository.max.storage.time>
<nifi.provenance.repository.max.storage.size>1 GB</nifi.provenance.repository.max.storage.size>
<nifi.provenance.repository.rollover.time>5 mins</nifi.provenance.repository.rollover.time>
<nifi.provenance.repository.rollover.size>100 MB</nifi.provenance.repository.rollover.size>
<nifi.provenance.repository.query.threads>2</nifi.provenance.repository.query.threads>
<nifi.provenance.repository.compress.on.rollover>true</nifi.provenance.repository.compress.on.rollover>
<nifi.provenance.repository.indexed.fields>EventType, FlowFileUUID, Filename, ProcessorID</nifi.provenance.repository.indexed.fields>
<nifi.provenance.repository.indexed.attributes />
<nifi.provenance.repository.index.shard.size>500 MB</nifi.provenance.repository.index.shard.size>
<nifi.provenance.repository.always.sync>false</nifi.provenance.repository.always.sync>
<nifi.provenance.repository.journal.count>16</nifi.provenance.repository.journal.count>
<!-- volatile provenance repository properties -->
<nifi.provenance.repository.buffer.size>100000</nifi.provenance.repository.buffer.size>
<!-- Component status repository properties -->
<nifi.components.status.repository.implementation>org.apache.nifi.controller.status.history.VolatileComponentStatusRepository</nifi.components.status.repository.implementation>
<nifi.components.status.repository.buffer.size>288</nifi.components.status.repository.buffer.size>
<nifi.components.status.snapshot.frequency>5 mins</nifi.components.status.snapshot.frequency>
<!-- nifi.properties: web properties -->
<nifi.web.war.directory>./lib</nifi.web.war.directory>
<nifi.web.http.host />
<nifi.web.http.port>8080</nifi.web.http.port>
<nifi.web.https.host />
<nifi.web.https.port />
<nifi.jetty.work.dir>./work/jetty</nifi.jetty.work.dir>
<nifi.web.jetty.threads>200</nifi.web.jetty.threads>
<!-- nifi.properties: security properties -->
<nifi.security.keystore />
<nifi.security.keystoreType />
<nifi.security.keystorePasswd />
<nifi.security.keyPasswd />
<nifi.security.truststore />
<nifi.security.truststoreType />
<nifi.security.truststorePasswd />
<nifi.security.needClientAuth />
<nifi.security.authorizedUsers.file>./conf/authorized-users.xml</nifi.security.authorizedUsers.file>
<nifi.security.user.credential.cache.duration>24 hours</nifi.security.user.credential.cache.duration>
<nifi.security.user.authority.provider>file-provider</nifi.security.user.authority.provider>
<nifi.security.x509.principal.extractor />
<nifi.security.support.new.account.requests />
<nifi.security.ocsp.responder.url />
<nifi.security.ocsp.responder.certificate />
<!-- nifi.properties: cluster common properties (cluster manager and nodes must have same values) -->
<nifi.cluster.protocol.heartbeat.interval>5 sec</nifi.cluster.protocol.heartbeat.interval>
<nifi.cluster.protocol.is.secure>false</nifi.cluster.protocol.is.secure>
<nifi.cluster.protocol.socket.timeout>30 sec</nifi.cluster.protocol.socket.timeout>
<nifi.cluster.protocol.connection.handshake.timeout>45 sec</nifi.cluster.protocol.connection.handshake.timeout>
<nifi.cluster.protocol.use.multicast>false</nifi.cluster.protocol.use.multicast>
<nifi.cluster.protocol.multicast.address />
<nifi.cluster.protocol.multicast.port />
<nifi.cluster.protocol.multicast.service.broadcast.delay>500 ms</nifi.cluster.protocol.multicast.service.broadcast.delay>
<nifi.cluster.protocol.multicast.service.locator.attempts>3</nifi.cluster.protocol.multicast.service.locator.attempts>
<nifi.cluster.protocol.multicast.service.locator.attempts.delay>1 sec</nifi.cluster.protocol.multicast.service.locator.attempts.delay>
<nifi.flow.configuration.file>./conf/flow.xml.gz</nifi.flow.configuration.file>
<nifi.flow.configuration.archive.dir>./conf/archive/</nifi.flow.configuration.archive.dir>
<nifi.authority.provider.configuration.file>./conf/authority-providers.xml</nifi.authority.provider.configuration.file>
<nifi.templates.directory>./conf/templates</nifi.templates.directory>
<nifi.database.directory>./database_repository</nifi.database.directory>
<!-- nifi.properties: cluster node properties (only configure for cluster nodes) -->
<nifi.cluster.is.node>false</nifi.cluster.is.node>
<nifi.cluster.node.address />
<nifi.cluster.node.protocol.port />
<nifi.cluster.node.protocol.threads>2</nifi.cluster.node.protocol.threads>
<nifi.cluster.node.unicast.manager.address />
<nifi.cluster.node.unicast.manager.protocol.port />
<!-- nifi.properties: cluster manager properties (only configure for cluster manager) -->
<nifi.cluster.is.manager>false</nifi.cluster.is.manager>
<nifi.cluster.manager.address />
<nifi.cluster.manager.protocol.port />
<nifi.cluster.manager.node.firewall.file />
<nifi.cluster.manager.node.event.history.size>10</nifi.cluster.manager.node.event.history.size>
<nifi.cluster.manager.node.api.connection.timeout>30 sec</nifi.cluster.manager.node.api.connection.timeout>
<nifi.cluster.manager.node.api.read.timeout>30 sec</nifi.cluster.manager.node.api.read.timeout>
<nifi.cluster.manager.node.api.request.threads>10</nifi.cluster.manager.node.api.request.threads>
<nifi.cluster.manager.flow.retrieval.delay>5 sec</nifi.cluster.manager.flow.retrieval.delay>
<nifi.cluster.manager.protocol.threads>10</nifi.cluster.manager.protocol.threads>
<nifi.cluster.manager.safemode.duration>0 sec</nifi.cluster.manager.safemode.duration>
</properties>
<profiles>
<profile>
<id>rpm</id>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
<build>
<plugins>
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>unpack-shared-resources</id>
<goals>
<goal>unpack-dependencies</goal>
</goals>
<phase>generate-resources</phase>
<configuration>
<outputDirectory>${project.build.directory}/generated-resources</outputDirectory>
<includeArtifactIds>nifi-resources</includeArtifactIds>
<includeGroupIds>org.apache.nifi</includeGroupIds>
<excludeTransitive>false</excludeTransitive>
</configuration>
</execution>
<execution>
<id>unpack-docs</id>
<goals>
<goal>unpack-dependencies</goal>
</goals>
<phase>generate-resources</phase>
<configuration>
<outputDirectory>${project.build.directory}/generated-docs</outputDirectory>
<includeArtifactIds>nifi-docs</includeArtifactIds>
<includeGroupIds>org.apache.nifi</includeGroupIds>
<excludeTransitive>false</excludeTransitive>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>rpm-maven-plugin</artifactId>
<configuration>
<summary>Apache NiFi (incubating)</summary>
<description>Apache Nifi (incubating) is dataflow system based on the Flow-Based Programming concepts.</description>
<license>Apache License, Version 2.0 and others (see included LICENSE file)</license>
<url>http://nifi.incubator.apache.org</url>
<group>Utilities</group>
<prefix>/opt/nifi</prefix>
<defineStatements>
<defineStatement>_use_internal_dependency_generator 0</defineStatement>
</defineStatements>
<defaultDirmode>750</defaultDirmode>
<defaultFilemode>640</defaultFilemode>
<defaultUsername>root</defaultUsername>
<defaultGroupname>root</defaultGroupname>
</configuration>
<executions>
<execution>
<id>build-bin-rpm</id>
<goals>
<goal>attached-rpm</goal>
</goals>
<configuration>
<classifier>bin</classifier>
<provides>
<provide>nifi</provide>
</provides>
<mappings>
<mapping>
<directory>/opt/nifi/nifi-${project.version}</directory>
</mapping>
<mapping>
<directory>/opt/nifi/nifi-${project.version}</directory>
<sources>
<source>
<location>./LICENSE</location>
</source>
<source>
<location>./NOTICE</location>
</source>
<source>
<location>../DISCLAIMER</location>
</source>
<source>
<location>./README.md</location>
<destination>README</destination>
</source>
</sources>
</mapping>
<mapping>
<directory>/opt/nifi/nifi-${project.version}/bin</directory>
<filemode>750</filemode>
<sources>
<source>
<location>${project.build.directory}/generated-resources/bin/nifi.sh</location>
<destination>nifi.sh</destination>
<filter>true</filter>
</source>
</sources>
</mapping>
<mapping>
<directory>/opt/nifi/nifi-${project.version}/conf</directory>
<configuration>true</configuration>
<sources>
<source>
<location>${project.build.directory}/generated-resources/conf</location>
<filter>true</filter>
</source>
</sources>
</mapping>
<mapping>
<directory>/opt/nifi/nifi-${project.version}/lib</directory>
<dependency>
<excludes>
<exclude>org.apache.nifi:nifi-bootstrap</exclude>
<exclude>org.apache.nifi:nifi-resources</exclude>
<exclude>org.apache.nifi:nifi-docs</exclude>
</excludes>
</dependency>
</mapping>
<mapping>
<directory>/opt/nifi/nifi-${project.version}/lib/bootstrap</directory>
<dependency>
<includes>
<include>org.apache.nifi:nifi-bootstrap</include>
</includes>
</dependency>
</mapping>
<mapping>
<directory>/opt/nifi/nifi-${project.version}/docs</directory>
<sources>
<source>
<location>${project.build.directory}/generated-docs</location>
</source>
</sources>
</mapping>
</mappings>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
<nifi.flowfile.repository.implementation>org.apache.nifi.controller.repository.WriteAheadFlowFileRepository</nifi.flowfile.repository.implementation>
<nifi.flowfile.repository.directory>./flowfile_repository</nifi.flowfile.repository.directory>
<nifi.flowfile.repository.partitions>256</nifi.flowfile.repository.partitions>
<nifi.flowfile.repository.checkpoint.interval>2 mins</nifi.flowfile.repository.checkpoint.interval>
<nifi.flowfile.repository.always.sync>false</nifi.flowfile.repository.always.sync>
<nifi.swap.manager.implementation>org.apache.nifi.controller.FileSystemSwapManager</nifi.swap.manager.implementation>
<nifi.queue.swap.threshold>20000</nifi.queue.swap.threshold>
<nifi.swap.in.period>5 sec</nifi.swap.in.period>
<nifi.swap.in.threads>1</nifi.swap.in.threads>
<nifi.swap.out.period>5 sec</nifi.swap.out.period>
<nifi.swap.out.threads>4</nifi.swap.out.threads>
<nifi.content.repository.implementation>org.apache.nifi.controller.repository.FileSystemRepository</nifi.content.repository.implementation>
<nifi.content.claim.max.appendable.size>10 MB</nifi.content.claim.max.appendable.size>
<nifi.content.claim.max.flow.files>100</nifi.content.claim.max.flow.files>
<nifi.content.repository.directory.default>./content_repository</nifi.content.repository.directory.default>
<nifi.content.repository.archive.max.retention.period />
<nifi.content.repository.archive.max.usage.percentage />
<nifi.content.repository.archive.enabled>false</nifi.content.repository.archive.enabled>
<nifi.content.repository.always.sync>false</nifi.content.repository.always.sync>
<nifi.content.viewer.url />
<nifi.restore.directory />
<nifi.ui.banner.text />
<nifi.ui.autorefresh.interval>30 sec</nifi.ui.autorefresh.interval>
<nifi.nar.library.directory>./lib</nifi.nar.library.directory>
<nifi.nar.working.directory>./work/nar/</nifi.nar.working.directory>
<nifi.documentation.working.directory>./work/docs/components</nifi.documentation.working.directory>
<nifi.sensitive.props.algorithm>PBEWITHMD5AND256BITAES-CBC-OPENSSL</nifi.sensitive.props.algorithm>
<nifi.sensitive.props.provider>BC</nifi.sensitive.props.provider>
<nifi.h2.url.append>;LOCK_TIMEOUT=25000;WRITE_DELAY=0;AUTO_SERVER=FALSE</nifi.h2.url.append>
<nifi.remote.input.socket.port>9990</nifi.remote.input.socket.port>
<!-- persistent provenance repository properties -->
<nifi.provenance.repository.implementation>org.apache.nifi.provenance.PersistentProvenanceRepository</nifi.provenance.repository.implementation>
<nifi.provenance.repository.directory.default>./provenance_repository</nifi.provenance.repository.directory.default>
<nifi.provenance.repository.max.storage.time>24 hours</nifi.provenance.repository.max.storage.time>
<nifi.provenance.repository.max.storage.size>1 GB</nifi.provenance.repository.max.storage.size>
<nifi.provenance.repository.rollover.time>5 mins</nifi.provenance.repository.rollover.time>
<nifi.provenance.repository.rollover.size>100 MB</nifi.provenance.repository.rollover.size>
<nifi.provenance.repository.query.threads>2</nifi.provenance.repository.query.threads>
<nifi.provenance.repository.compress.on.rollover>true</nifi.provenance.repository.compress.on.rollover>
<nifi.provenance.repository.indexed.fields>EventType, FlowFileUUID,
Filename, ProcessorID</nifi.provenance.repository.indexed.fields>
<nifi.provenance.repository.indexed.attributes />
<nifi.provenance.repository.index.shard.size>500 MB</nifi.provenance.repository.index.shard.size>
<nifi.provenance.repository.always.sync>false</nifi.provenance.repository.always.sync>
<nifi.provenance.repository.journal.count>16</nifi.provenance.repository.journal.count>
<!-- volatile provenance repository properties -->
<nifi.provenance.repository.buffer.size>100000</nifi.provenance.repository.buffer.size>
<!-- Component status repository properties -->
<nifi.components.status.repository.implementation>org.apache.nifi.controller.status.history.VolatileComponentStatusRepository</nifi.components.status.repository.implementation>
<nifi.components.status.repository.buffer.size>288</nifi.components.status.repository.buffer.size>
<nifi.components.status.snapshot.frequency>5 mins</nifi.components.status.snapshot.frequency>
<!-- nifi.properties: web properties -->
<nifi.web.war.directory>./lib</nifi.web.war.directory>
<nifi.web.http.host />
<nifi.web.http.port>8080</nifi.web.http.port>
<nifi.web.https.host />
<nifi.web.https.port />
<nifi.jetty.work.dir>./work/jetty</nifi.jetty.work.dir>
<nifi.web.jetty.threads>200</nifi.web.jetty.threads>
<!-- nifi.properties: security properties -->
<nifi.security.keystore />
<nifi.security.keystoreType />
<nifi.security.keystorePasswd />
<nifi.security.keyPasswd />
<nifi.security.truststore />
<nifi.security.truststoreType />
<nifi.security.truststorePasswd />
<nifi.security.needClientAuth />
<nifi.security.authorizedUsers.file>./conf/authorized-users.xml</nifi.security.authorizedUsers.file>
<nifi.security.user.credential.cache.duration>24 hours</nifi.security.user.credential.cache.duration>
<nifi.security.user.authority.provider>file-provider</nifi.security.user.authority.provider>
<nifi.security.x509.principal.extractor />
<nifi.security.support.new.account.requests />
<nifi.security.ocsp.responder.url />
<nifi.security.ocsp.responder.certificate />
<!-- nifi.properties: cluster common properties (cluster manager and nodes
must have same values) -->
<nifi.cluster.protocol.heartbeat.interval>5 sec</nifi.cluster.protocol.heartbeat.interval>
<nifi.cluster.protocol.is.secure>false</nifi.cluster.protocol.is.secure>
<nifi.cluster.protocol.socket.timeout>30 sec</nifi.cluster.protocol.socket.timeout>
<nifi.cluster.protocol.connection.handshake.timeout>45 sec</nifi.cluster.protocol.connection.handshake.timeout>
<nifi.cluster.protocol.use.multicast>false</nifi.cluster.protocol.use.multicast>
<nifi.cluster.protocol.multicast.address />
<nifi.cluster.protocol.multicast.port />
<nifi.cluster.protocol.multicast.service.broadcast.delay>500 ms</nifi.cluster.protocol.multicast.service.broadcast.delay>
<nifi.cluster.protocol.multicast.service.locator.attempts>3</nifi.cluster.protocol.multicast.service.locator.attempts>
<nifi.cluster.protocol.multicast.service.locator.attempts.delay>1 sec</nifi.cluster.protocol.multicast.service.locator.attempts.delay>
<!-- nifi.properties: cluster node properties (only configure for cluster
nodes) -->
<nifi.cluster.is.node>false</nifi.cluster.is.node>
<nifi.cluster.node.address />
<nifi.cluster.node.protocol.port />
<nifi.cluster.node.protocol.threads>2</nifi.cluster.node.protocol.threads>
<nifi.cluster.node.unicast.manager.address />
<nifi.cluster.node.unicast.manager.protocol.port />
<!-- nifi.properties: cluster manager properties (only configure for cluster
manager) -->
<nifi.cluster.is.manager>false</nifi.cluster.is.manager>
<nifi.cluster.manager.address />
<nifi.cluster.manager.protocol.port />
<nifi.cluster.manager.node.firewall.file />
<nifi.cluster.manager.node.event.history.size>10</nifi.cluster.manager.node.event.history.size>
<nifi.cluster.manager.node.api.connection.timeout>30 sec</nifi.cluster.manager.node.api.connection.timeout>
<nifi.cluster.manager.node.api.read.timeout>30 sec</nifi.cluster.manager.node.api.read.timeout>
<nifi.cluster.manager.node.api.request.threads>10</nifi.cluster.manager.node.api.request.threads>
<nifi.cluster.manager.flow.retrieval.delay>5 sec</nifi.cluster.manager.flow.retrieval.delay>
<nifi.cluster.manager.protocol.threads>10</nifi.cluster.manager.protocol.threads>
<nifi.cluster.manager.safemode.duration>0 sec</nifi.cluster.manager.safemode.duration>
</properties>
<profiles>
<profile>
<id>rpm</id>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
<build>
<plugins>
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>unpack-shared-resources</id>
<goals>
<goal>unpack-dependencies</goal>
</goals>
<phase>generate-resources</phase>
<configuration>
<outputDirectory>${project.build.directory}/generated-resources</outputDirectory>
<includeArtifactIds>nifi-resources</includeArtifactIds>
<includeGroupIds>org.apache.nifi</includeGroupIds>
<excludeTransitive>false</excludeTransitive>
</configuration>
</execution>
<execution>
<id>unpack-docs</id>
<goals>
<goal>unpack-dependencies</goal>
</goals>
<phase>generate-resources</phase>
<configuration>
<outputDirectory>${project.build.directory}/generated-docs</outputDirectory>
<includeArtifactIds>nifi-docs</includeArtifactIds>
<includeGroupIds>org.apache.nifi</includeGroupIds>
<excludeTransitive>false</excludeTransitive>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>rpm-maven-plugin</artifactId>
<configuration>
<summary>Apache NiFi (incubating)</summary>
<description>Apache Nifi (incubating) is dataflow system based on
the Flow-Based Programming concepts.</description>
<license>Apache License, Version 2.0 and others (see included
LICENSE file)</license>
<url>http://nifi.incubator.apache.org</url>
<group>Utilities</group>
<prefix>/opt/nifi</prefix>
<defineStatements>
<defineStatement>_use_internal_dependency_generator 0</defineStatement>
</defineStatements>
<defaultDirmode>750</defaultDirmode>
<defaultFilemode>640</defaultFilemode>
<defaultUsername>root</defaultUsername>
<defaultGroupname>root</defaultGroupname>
</configuration>
<executions>
<execution>
<id>build-bin-rpm</id>
<goals>
<goal>attached-rpm</goal>
</goals>
<configuration>
<classifier>bin</classifier>
<provides>
<provide>nifi</provide>
</provides>
<mappings>
<mapping>
<directory>/opt/nifi/nifi-${project.version}</directory>
</mapping>
<mapping>
<directory>/opt/nifi/nifi-${project.version}</directory>
<sources>
<source>
<location>./LICENSE</location>
</source>
<source>
<location>./NOTICE</location>
</source>
<source>
<location>../DISCLAIMER</location>
</source>
<source>
<location>./README.md</location>
<destination>README</destination>
</source>
</sources>
</mapping>
<mapping>
<directory>/opt/nifi/nifi-${project.version}/bin</directory>
<filemode>750</filemode>
<sources>
<source>
<location>${project.build.directory}/generated-resources/bin/nifi.sh</location>
<destination>nifi.sh</destination>
<filter>true</filter>
</source>
</sources>
</mapping>
<mapping>
<directory>/opt/nifi/nifi-${project.version}/conf</directory>
<configuration>true</configuration>
<sources>
<source>
<location>${project.build.directory}/generated-resources/conf</location>
<filter>true</filter>
</source>
</sources>
</mapping>
<mapping>
<directory>/opt/nifi/nifi-${project.version}/lib</directory>
<dependency>
<excludes>
<exclude>org.apache.nifi:nifi-bootstrap</exclude>
<exclude>org.apache.nifi:nifi-resources</exclude>
<exclude>org.apache.nifi:nifi-docs</exclude>
</excludes>
</dependency>
</mapping>
<mapping>
<directory>/opt/nifi/nifi-${project.version}/lib/bootstrap</directory>
<dependency>
<includes>
<include>org.apache.nifi:nifi-bootstrap</include>
</includes>
</dependency>
</mapping>
<mapping>
<directory>/opt/nifi/nifi-${project.version}/docs</directory>
<sources>
<source>
<location>${project.build.directory}/generated-docs</location>
</source>
</sources>
</mapping>
</mappings>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>

View File

@ -17,7 +17,7 @@
<parent>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi</artifactId>
<version>0.0.2-incubating-SNAPSHOT</version>
<version>0.1.0-incubating-SNAPSHOT</version>
</parent>
<artifactId>nifi-bootstrap</artifactId>
<packaging>jar</packaging>

View File

@ -45,9 +45,10 @@ import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.logging.ConsoleHandler;
import java.util.logging.FileHandler;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.SimpleFormatter;
/**
@ -92,16 +93,82 @@ public class RunNiFi {
private final java.util.logging.Logger logger;
public RunNiFi(final File bootstrapConfigFile, final boolean verbose) {
public RunNiFi(final File bootstrapConfigFile, final boolean verbose) throws IOException {
this.bootstrapConfigFile = bootstrapConfigFile;
logger = java.util.logging.Logger.getLogger("Bootstrap");
final Properties bootstrapProps = new Properties();
try (final InputStream configIn = new FileInputStream(bootstrapConfigFile)) {
bootstrapProps.load(configIn);
}
String logFilename = bootstrapProps.getProperty("bootstrap.log.file");
if ( logFilename == null ) {
logFilename = "./logs/bootstrap.log";
}
File logFile = new File(logFilename);
if ( !logFile.isAbsolute() ) {
final File workDir = getDefaultWorkingDirectory();
logFile = new File(workDir, logFilename);
}
final File logFileDir = logFile.getParentFile();
final Handler fileHandler;
if ( logFileDir.exists() || logFileDir.mkdirs() ) {
final int maxSize = getIntProp(bootstrapProps, "bootstrap.log.max.bytes", 1024 * 1024 * 10); // 10 MB
final int numFiles = getIntProp(bootstrapProps, "bootstrap.log.count", 10);
fileHandler = new FileHandler(logFile.getAbsolutePath(), maxSize, numFiles, true);
fileHandler.setFormatter(new SimpleFormatter());
logger.addHandler(fileHandler);
} else {
fileHandler = null;
logger.severe("Could not create log file directory " + logFileDir + ". Will not log bootstrap info to file or redirect NiFi standard out to file");
}
if ( verbose ) {
logger.info("Enabling Verbose Output");
logger.setLevel(Level.FINE);
final Handler handler = new ConsoleHandler();
handler.setLevel(Level.FINE);
logger.addHandler(handler);
for ( final Handler handler : logger.getHandlers() ) {
handler.setLevel(Level.FINE);
}
}
}
private File getLogFile() throws IOException {
final Properties bootstrapProps = new Properties();
try (final InputStream configIn = new FileInputStream(bootstrapConfigFile)) {
bootstrapProps.load(configIn);
}
String logFilename = bootstrapProps.getProperty("bootstrap.log.file");
if ( logFilename == null ) {
logFilename = "./logs/bootstrap.log";
}
File logFile = new File(logFilename);
if ( !logFile.isAbsolute() ) {
final File workDir = getDefaultWorkingDirectory();
logFile = new File(workDir, logFilename);
}
return logFile;
}
private static int getIntProp(final Properties properties, final String name, final int defaultValue) {
String propVal = properties.getProperty(name);
if ( propVal == null || propVal.trim().isEmpty() ) {
return defaultValue;
}
try {
return Integer.parseInt(propVal.trim());
} catch (final NumberFormatException nfe) {
throw new NumberFormatException("Expected bootstrap property '" + name + "' to be an integer but found value: " + propVal);
}
}
@ -581,6 +648,35 @@ public class RunNiFi {
}
}
private void redirectOutput(final Process process) {
redirectStreamToLogs(process.getInputStream());
redirectStreamToLogs(process.getErrorStream());
}
private void redirectStreamToLogs(final InputStream in) {
final Thread t = new Thread(new Runnable() {
@Override
public void run() {
try (final BufferedReader reader = new BufferedReader(new InputStreamReader(in))) {
String line;
while ((line = reader.readLine()) != null) {
logger.info(line);
}
} catch (IOException e) {
logger.warning("Failed to read output of NiFi console: " + e);
}
}
});
t.setDaemon(true);
t.start();
}
private File getDefaultWorkingDirectory() {
final File bootstrapConfigAbsoluteFile = bootstrapConfigFile.getAbsoluteFile();
final File binDir = bootstrapConfigAbsoluteFile.getParentFile();
return binDir.getParentFile();
}
@SuppressWarnings({ "rawtypes", "unchecked" })
public void start(final boolean monitor) throws IOException, InterruptedException {
final Integer port = getCurrentPort();
@ -590,7 +686,6 @@ public class RunNiFi {
}
final ProcessBuilder builder = new ProcessBuilder();
if ( !bootstrapConfigFile.exists() ) {
throw new FileNotFoundException(bootstrapConfigFile.getAbsolutePath());
}
@ -604,18 +699,17 @@ public class RunNiFi {
props.putAll( (Map) properties );
final String specifiedWorkingDir = props.get("working.dir");
if ( specifiedWorkingDir != null ) {
builder.directory(new File(specifiedWorkingDir));
}
final File bootstrapConfigAbsoluteFile = bootstrapConfigFile.getAbsoluteFile();
final File binDir = bootstrapConfigAbsoluteFile.getParentFile();
final File workingDir = binDir.getParentFile();
final File workingDir = getDefaultWorkingDirectory();
if ( specifiedWorkingDir == null ) {
builder.directory(workingDir);
} else {
builder.directory(new File(specifiedWorkingDir));
}
final File logDir = getLogFile().getParentFile();
builder.redirectError(new File(logDir, "nifi.err"));
builder.redirectOutput(new File(logDir, "nifi.out"));
final String libFilename = replaceNull(props.get("lib.dir"), "./lib").trim();
File libDir = getFile(libFilename, workingDir);
@ -738,14 +832,15 @@ public class RunNiFi {
try {
gracefulShutdownSeconds = Integer.parseInt(gracefulShutdown);
} catch (final NumberFormatException nfe) {
throw new NumberFormatException("The '" + GRACEFUL_SHUTDOWN_PROP + "' property in Bootstrap Config File " + bootstrapConfigAbsoluteFile.getAbsolutePath() + " has an invalid value. Must be a non-negative integer");
throw new NumberFormatException("The '" + GRACEFUL_SHUTDOWN_PROP + "' property in Bootstrap Config File " + bootstrapConfigFile.getAbsolutePath() + " has an invalid value. Must be a non-negative integer");
}
if ( gracefulShutdownSeconds < 0 ) {
throw new NumberFormatException("The '" + GRACEFUL_SHUTDOWN_PROP + "' property in Bootstrap Config File " + bootstrapConfigAbsoluteFile.getAbsolutePath() + " has an invalid value. Must be a non-negative integer");
throw new NumberFormatException("The '" + GRACEFUL_SHUTDOWN_PROP + "' property in Bootstrap Config File " + bootstrapConfigFile.getAbsolutePath() + " has an invalid value. Must be a non-negative integer");
}
Process process = builder.start();
redirectOutput(process);
Long pid = getPid(process);
if ( pid != null ) {
nifiPid = pid;
@ -776,7 +871,8 @@ public class RunNiFi {
if (autoRestartNiFi) {
logger.warning("Apache NiFi appears to have died. Restarting...");
process = builder.start();
redirectOutput(process);
pid = getPid(process);
if ( pid != null ) {
nifiPid = pid;
@ -802,6 +898,7 @@ public class RunNiFi {
}
} else {
final Process process = builder.start();
redirectOutput(process);
final Long pid = getPid(process);
if ( pid != null ) {

View File

@ -17,7 +17,7 @@
<parent>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-commons</artifactId>
<version>0.0.2-incubating-SNAPSHOT</version>
<version>0.1.0-incubating-SNAPSHOT</version>
</parent>
<artifactId>nifi-data-provenance-utils</artifactId>
<packaging>jar</packaging>

View File

@ -17,7 +17,7 @@
<parent>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-commons</artifactId>
<version>0.0.2-incubating-SNAPSHOT</version>
<version>0.1.0-incubating-SNAPSHOT</version>
</parent>
<artifactId>nifi-expression-language</artifactId>
<packaging>jar</packaging>

View File

@ -17,7 +17,7 @@
<parent>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-commons</artifactId>
<version>0.0.2-incubating-SNAPSHOT</version>
<version>0.1.0-incubating-SNAPSHOT</version>
</parent>
<artifactId>nifi-flowfile-packager</artifactId>
<packaging>jar</packaging>

View File

@ -0,0 +1,3 @@
/target/
/target/
/target/

View File

@ -0,0 +1,115 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
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.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-commons</artifactId>
<version>0.1.0-incubating-SNAPSHOT</version>
</parent>
<artifactId>nifi-hl7-query-language</artifactId>
<packaging>jar</packaging>
<name>NiFi Health Level 7 (HL7) Query Language</name>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
<plugin>
<groupId>org.antlr</groupId>
<artifactId>antlr3-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>antlr</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.antlr</groupId>
<artifactId>antlr-runtime</artifactId>
<version>3.5.2</version>
</dependency>
<!-- HAPI to parse v2 messages -->
<dependency>
<groupId>ca.uhn.hapi</groupId>
<artifactId>hapi-base</artifactId>
<version>2.2</version>
</dependency>
<dependency>
<groupId>ca.uhn.hapi</groupId>
<artifactId>hapi-structures-v21</artifactId>
<version>2.2</version>
</dependency>
<dependency>
<groupId>ca.uhn.hapi</groupId>
<artifactId>hapi-structures-v22</artifactId>
<version>2.2</version>
</dependency>
<dependency>
<groupId>ca.uhn.hapi</groupId>
<artifactId>hapi-structures-v23</artifactId>
<version>2.2</version>
</dependency>
<dependency>
<groupId>ca.uhn.hapi</groupId>
<artifactId>hapi-structures-v231</artifactId>
<version>2.2</version>
</dependency>
<dependency>
<groupId>ca.uhn.hapi</groupId>
<artifactId>hapi-structures-v24</artifactId>
<version>2.2</version>
</dependency>
<dependency>
<groupId>ca.uhn.hapi</groupId>
<artifactId>hapi-structures-v25</artifactId>
<version>2.2</version>
</dependency>
<dependency>
<groupId>ca.uhn.hapi</groupId>
<artifactId>hapi-structures-v251</artifactId>
<version>2.2</version>
</dependency>
<dependency>
<groupId>ca.uhn.hapi</groupId>
<artifactId>hapi-structures-v26</artifactId>
<version>2.2</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,156 @@
lexer grammar HL7QueryLexer;
@header {
package org.apache.nifi.hl7.query.antlr;
import org.apache.nifi.hl7.query.exception.HL7QueryParsingException;
}
@rulecatch {
catch(final Exception e) {
throw new HL7QueryParsingException(e);
}
}
@members {
public void displayRecognitionError(String[] tokenNames, RecognitionException e) {
final StringBuilder sb = new StringBuilder();
if ( e.token == null ) {
sb.append("Unrecognized token ");
} else {
sb.append("Unexpected token '").append(e.token.getText()).append("' ");
}
sb.append("at line ").append(e.line);
if ( e.approximateLineInfo ) {
sb.append(" (approximately)");
}
sb.append(", column ").append(e.charPositionInLine);
sb.append(". Query: ").append(e.input.toString());
throw new HL7QueryParsingException(sb.toString());
}
public void recover(RecognitionException e) {
final StringBuilder sb = new StringBuilder();
if ( e.token == null ) {
sb.append("Unrecognized token ");
} else {
sb.append("Unexpected token '").append(e.token.getText()).append("' ");
}
sb.append("at line ").append(e.line);
if ( e.approximateLineInfo ) {
sb.append(" (approximately)");
}
sb.append(", column ").append(e.charPositionInLine);
sb.append(". Query: ").append(e.input.toString());
throw new HL7QueryParsingException(sb.toString());
}
}
// PUNCTUATION & SPECIAL CHARACTERS
WHITESPACE : (' '|'\t'|'\n'|'\r')+ { $channel = HIDDEN; };
COMMENT : '#' ( ~('\n') )* '\n' { $channel = HIDDEN; };
LPAREN : '(';
RPAREN : ')';
LBRACE : '{';
RBRACE : '}';
COLON : ':';
COMMA : ',';
DOT : '.';
SEMICOLON : ';';
// OPERATORS
EQUALS : '=';
NOT_EQUALS : '!=';
GT : '>';
GE : '>=';
LT : '<';
LE : '<=';
REGEX : 'MATCHES REGEX';
LIKE : 'LIKE';
IS_NULL : 'IS NULL';
NOT_NULL : 'NOT NULL';
// KEYWORDS
AND : 'AND';
OR : 'OR';
NOT : 'NOT';
TRUE : 'true';
FALSE : 'false';
SELECT : 'select' | 'SELECT';
DECLARE : 'declare' | 'DECLARE';
OPTIONAL : 'optional' | 'OPTIONAL';
REQUIRED : 'required' | 'REQUIRED';
AS : 'as' | 'AS';
WHERE : 'where' | 'WHERE';
MESSAGE : 'MESSAGE' | 'message';
SEGMENT : 'SEGMENT' | 'segment';
SEGMENT_NAME : LETTER ALPHA_NUMERIC ALPHA_NUMERIC;
NUMBER : ('0'..'9')+;
fragment LETTER : 'A'..'Z';
fragment ALPHA_NUMERIC : 'A'..'Z' | '0'..'9';
// STRINGS
STRING_LITERAL
@init{StringBuilder lBuf = new StringBuilder();}
:
(
'"'
(
escaped=ESC {lBuf.append(getText());} |
normal = ~( '"' | '\\' | '\n' | '\r' | '\t' ) { lBuf.appendCodePoint(normal);}
)*
'"'
)
{
setText(lBuf.toString());
}
|
(
'\''
(
escaped=ESC {lBuf.append(getText());} |
normal = ~( '\'' | '\\' | '\n' | '\r' | '\t' ) { lBuf.appendCodePoint(normal);}
)*
'\''
)
{
setText(lBuf.toString());
}
;
fragment
ESC
: '\\'
(
'"' { setText("\""); }
| '\'' { setText("\'"); }
| 'r' { setText("\r"); }
| 'n' { setText("\n"); }
| 't' { setText("\t"); }
| '\\' { setText("\\\\"); }
| nextChar = ~('"' | '\'' | 'r' | 'n' | 't' | '\\')
{
StringBuilder lBuf = new StringBuilder(); lBuf.append("\\\\").appendCodePoint(nextChar); setText(lBuf.toString());
}
)
;
IDENTIFIER : (
~('$' | '{' | '}' | '(' | ')' | '[' | ']' | ',' | ':' | ';' | '/' | '*' | '\'' | ' ' | '\t' | '\r' | '\n' | '0'..'9' | '.')
~('$' | '{' | '}' | '(' | ')' | '[' | ']' | ',' | ':' | ';' | '/' | '*' | '\'' | ' ' | '\t' | '\r' | '\n' | '.')*
);

View File

@ -0,0 +1,91 @@
parser grammar HL7QueryParser;
options {
output=AST;
tokenVocab=HL7QueryLexer;
}
tokens {
QUERY;
DECLARATION;
}
@header {
package org.apache.nifi.hl7.query.antlr;
import org.apache.nifi.hl7.query.exception.HL7QueryParsingException;
}
@members {
public void displayRecognitionError(String[] tokenNames, RecognitionException e) {
final StringBuilder sb = new StringBuilder();
if ( e.token == null ) {
sb.append("Unrecognized token ");
} else {
sb.append("Unexpected token '").append(e.token.getText()).append("' ");
}
sb.append("at line ").append(e.line);
if ( e.approximateLineInfo ) {
sb.append(" (approximately)");
}
sb.append(", column ").append(e.charPositionInLine);
sb.append(". Query: ").append(e.input.toString());
throw new HL7QueryParsingException(sb.toString());
}
public void recover(final RecognitionException e) {
final StringBuilder sb = new StringBuilder();
if ( e.token == null ) {
sb.append("Unrecognized token ");
} else {
sb.append("Unexpected token '").append(e.token.getText()).append("' ");
}
sb.append("at line ").append(e.line);
if ( e.approximateLineInfo ) {
sb.append(" (approximately)");
}
sb.append(", column ").append(e.charPositionInLine);
sb.append(". Query: ").append(e.input.toString());
throw new HL7QueryParsingException(sb.toString());
}
}
declareClause : DECLARE^ declaration (COMMA! declaration)*;
requiredOrOptional : REQUIRED | OPTIONAL;
declaration : IDENTIFIER AS requiredOrOptional SEGMENT_NAME ->
^(DECLARATION IDENTIFIER requiredOrOptional SEGMENT_NAME);
selectClause : SELECT^ selectableClause;
selectableClause : selectable (COMMA! selectable)*;
selectable : (MESSAGE | ref | field)^ (AS! IDENTIFIER^)?;
whereClause : WHERE^ conditions;
conditions : condition ((AND^ | OR^) condition)*;
condition : NOT^ condition | LPAREN! conditions RPAREN! | evaluation;
evaluation : expression
(
unaryOperator^
| (binaryOperator^ expression)
);
expression : (LPAREN! expr RPAREN!) | expr;
expr : ref | field | STRING_LITERAL | NUMBER;
unaryOperator : IS_NULL | NOT_NULL;
binaryOperator : EQUALS | NOT_EQUALS | LT | GT | LE | GE;
ref : (SEGMENT_NAME | IDENTIFIER);
field : ref DOT^ NUMBER
(DOT^ NUMBER (DOT^ NUMBER (DOT^ NUMBER)?)?)?;
query : declareClause? selectClause whereClause? EOF ->
^(QUERY declareClause? selectClause whereClause?);

View File

@ -0,0 +1,37 @@
/*
* 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.nifi.hl7.hapi;
import java.util.Collections;
import java.util.List;
import org.apache.nifi.hl7.model.HL7Component;
import org.apache.nifi.hl7.model.HL7Field;
public class EmptyField implements HL7Field {
@Override
public String getValue() {
return null;
}
@Override
public List<HL7Component> getComponents() {
return Collections.emptyList();
}
}

View File

@ -0,0 +1,83 @@
/*
* 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.nifi.hl7.hapi;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.apache.nifi.hl7.model.HL7Component;
import org.apache.nifi.hl7.model.HL7Field;
import ca.uhn.hl7v2.model.Composite;
import ca.uhn.hl7v2.model.ExtraComponents;
import ca.uhn.hl7v2.model.Primitive;
import ca.uhn.hl7v2.model.Type;
import ca.uhn.hl7v2.model.Varies;
import ca.uhn.hl7v2.parser.EncodingCharacters;
import ca.uhn.hl7v2.parser.PipeParser;
public class HapiField implements HL7Field, HL7Component {
private final String value;
private final List<HL7Component> components;
public HapiField(final Type type) {
this.value = PipeParser.encode(type, EncodingCharacters.defaultInstance());
final List<HL7Component> componentList = new ArrayList<>();
if ( type instanceof Composite ) {
final Composite composite = (Composite) type;
for ( final Type component : composite.getComponents() ) {
componentList.add(new HapiField(component));
}
}
final ExtraComponents extra = type.getExtraComponents();
if ( extra != null && extra.numComponents() > 0 ) {
final String singleFieldValue;
if ( type instanceof Primitive ) {
singleFieldValue = ((Primitive) type).getValue();
} else {
singleFieldValue = this.value;
}
componentList.add(new SingleValueField(singleFieldValue));
for (int i=0; i < extra.numComponents(); i++) {
final Varies varies = extra.getComponent(i);
componentList.add(new HapiField(varies));
}
}
this.components = Collections.unmodifiableList(componentList);
}
@Override
public String getValue() {
return value;
}
@Override
public List<HL7Component> getComponents() {
return components;
}
@Override
public String toString() {
return value;
}
}

View File

@ -0,0 +1,94 @@
/*
* 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.nifi.hl7.hapi;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.nifi.hl7.model.HL7Message;
import org.apache.nifi.hl7.model.HL7Segment;
import ca.uhn.hl7v2.HL7Exception;
import ca.uhn.hl7v2.model.Group;
import ca.uhn.hl7v2.model.Message;
import ca.uhn.hl7v2.model.Segment;
import ca.uhn.hl7v2.model.Structure;
public class HapiMessage implements HL7Message {
private final Message message;
private final List<HL7Segment> allSegments;
private final Map<String, List<HL7Segment>> segmentMap;
public HapiMessage(final Message message) throws HL7Exception {
this.message = message;
allSegments = new ArrayList<>();
populateSegments(message, allSegments);
segmentMap = new HashMap<>();
for ( final HL7Segment segment : allSegments ) {
final String segmentName = segment.getName();
List<HL7Segment> segmentList = segmentMap.get(segmentName);
if ( segmentList == null ) {
segmentList = new ArrayList<>();
segmentMap.put(segmentName, segmentList);
}
segmentList.add(segment);
}
}
private void populateSegments(final Group group, final List<HL7Segment> segments) throws HL7Exception {
for ( final String structureName : group.getNames() ) {
final Structure[] structures = group.getAll(structureName);
if ( group.isGroup(structureName) ) {
for ( final Structure structure : structures ) {
populateSegments((Group) structure, segments);
}
} else {
for ( final Structure structure : structures ) {
final Segment segment = (Segment) structure;
final HapiSegment hapiSegment = new HapiSegment(segment);
segments.add(hapiSegment);
}
}
}
}
@Override
public List<HL7Segment> getSegments() {
return Collections.unmodifiableList(allSegments);
}
@Override
public List<HL7Segment> getSegments(final String segmentType) {
final List<HL7Segment> segments = segmentMap.get(segmentType);
if ( segments == null ) {
return Collections.emptyList();
}
return Collections.unmodifiableList(segments);
}
@Override
public String toString() {
return message.toString();
}
}

View File

@ -0,0 +1,69 @@
/*
* 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.nifi.hl7.hapi;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.apache.nifi.hl7.model.HL7Field;
import org.apache.nifi.hl7.model.HL7Segment;
import ca.uhn.hl7v2.HL7Exception;
import ca.uhn.hl7v2.model.Segment;
import ca.uhn.hl7v2.model.Type;
public class HapiSegment implements HL7Segment {
private final Segment segment;
private final List<HL7Field> fields;
public HapiSegment(final Segment segment) throws HL7Exception {
this.segment = segment;
final List<HL7Field> fieldList = new ArrayList<>();
for (int i=1; i <= segment.numFields(); i++) {
final Type[] types = segment.getField(i);
if ( types == null || types.length == 0 ) {
fieldList.add(new EmptyField());
continue;
}
for ( final Type type : types ) {
fieldList.add(new HapiField(type));
}
}
this.fields = Collections.unmodifiableList(fieldList);
}
@Override
public String getName() {
return segment.getName();
}
@Override
public List<HL7Field> getFields() {
return fields;
}
@Override
public String toString() {
return segment.toString();
}
}

View File

@ -0,0 +1,42 @@
/*
* 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.nifi.hl7.hapi;
import java.util.Collections;
import java.util.List;
import org.apache.nifi.hl7.model.HL7Component;
import org.apache.nifi.hl7.model.HL7Field;
public class SingleValueField implements HL7Field {
private final String value;
public SingleValueField(final String value) {
this.value = value;
}
@Override
public String getValue() {
return value;
}
@Override
public List<HL7Component> getComponents() {
return Collections.emptyList();
}
}

View File

@ -0,0 +1,27 @@
/*
* 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.nifi.hl7.io;
import java.io.IOException;
import org.apache.nifi.hl7.model.HL7Message;
public interface HL7Reader {
HL7Message nextMessage() throws IOException;
}

View File

@ -0,0 +1,40 @@
/*
* 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.nifi.hl7.io.exception;
import java.io.IOException;
public class InvalidHL7Exception extends IOException {
private static final long serialVersionUID = -5675416667224562441L;
public InvalidHL7Exception() {
super();
}
public InvalidHL7Exception(String message, Throwable cause) {
super(message, cause);
}
public InvalidHL7Exception(String message) {
super(message);
}
public InvalidHL7Exception(Throwable cause) {
super(cause);
}
}

View File

@ -0,0 +1,24 @@
/*
* 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.nifi.hl7.model;
import java.util.List;
public interface HL7Component {
String getValue();
List<HL7Component> getComponents();
}

View File

@ -14,11 +14,8 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.nifi.controller;
package org.apache.nifi.hl7.model;
public enum Availability {
CLUSTER_MANAGER_ONLY,
NODE_ONLY,
BOTH;
public interface HL7Field extends HL7Component {
}

View File

@ -0,0 +1,27 @@
/*
* 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.nifi.hl7.model;
import java.util.List;
public interface HL7Message {
List<HL7Segment> getSegments();
List<HL7Segment> getSegments(String segmentType);
}

View File

@ -0,0 +1,27 @@
/*
* 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.nifi.hl7.model;
import java.util.List;
public interface HL7Segment {
String getName();
List<HL7Field> getFields();
}

View File

@ -0,0 +1,29 @@
/*
* 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.nifi.hl7.query;
import org.apache.nifi.hl7.model.HL7Message;
public interface Declaration {
String getAlias();
boolean isRequired();
Object getDeclaredValue(HL7Message message);
}

View File

@ -0,0 +1,412 @@
/*
* 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.nifi.hl7.query;
import static org.apache.nifi.hl7.query.antlr.HL7QueryParser.*;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.antlr.runtime.ANTLRStringStream;
import org.antlr.runtime.CharStream;
import org.antlr.runtime.CommonTokenStream;
import org.antlr.runtime.tree.Tree;
import org.apache.nifi.hl7.model.HL7Message;
import org.apache.nifi.hl7.query.evaluator.BooleanEvaluator;
import org.apache.nifi.hl7.query.evaluator.Evaluator;
import org.apache.nifi.hl7.query.evaluator.IntegerEvaluator;
import org.apache.nifi.hl7.query.evaluator.comparison.EqualsEvaluator;
import org.apache.nifi.hl7.query.evaluator.comparison.GreaterThanEvaluator;
import org.apache.nifi.hl7.query.evaluator.comparison.GreaterThanOrEqualEvaluator;
import org.apache.nifi.hl7.query.evaluator.comparison.IsNullEvaluator;
import org.apache.nifi.hl7.query.evaluator.comparison.LessThanEvaluator;
import org.apache.nifi.hl7.query.evaluator.comparison.LessThanOrEqualEvaluator;
import org.apache.nifi.hl7.query.evaluator.comparison.NotEqualsEvaluator;
import org.apache.nifi.hl7.query.evaluator.comparison.NotEvaluator;
import org.apache.nifi.hl7.query.evaluator.comparison.NotNullEvaluator;
import org.apache.nifi.hl7.query.evaluator.literal.IntegerLiteralEvaluator;
import org.apache.nifi.hl7.query.evaluator.literal.StringLiteralEvaluator;
import org.apache.nifi.hl7.query.evaluator.logic.AndEvaluator;
import org.apache.nifi.hl7.query.evaluator.logic.OrEvaluator;
import org.apache.nifi.hl7.query.evaluator.message.DeclaredReferenceEvaluator;
import org.apache.nifi.hl7.query.evaluator.message.DotEvaluator;
import org.apache.nifi.hl7.query.evaluator.message.MessageEvaluator;
import org.apache.nifi.hl7.query.evaluator.message.SegmentEvaluator;
import org.apache.nifi.hl7.query.exception.HL7QueryParsingException;
import org.apache.nifi.hl7.query.result.MissedResult;
import org.apache.nifi.hl7.query.result.StandardQueryResult;
import org.apache.nifi.hl7.query.antlr.HL7QueryLexer;
import org.apache.nifi.hl7.query.antlr.HL7QueryParser;
public class HL7Query {
private final Tree tree;
private final String query;
private final Set<Declaration> declarations = new HashSet<>();
private final List<Selection> selections;
private final BooleanEvaluator whereEvaluator;
private HL7Query(final Tree tree, final String query) {
this.tree = tree;
this.query = query;
List<Selection> select = null;
BooleanEvaluator where = null;
for (int i=0; i < tree.getChildCount(); i++) {
final Tree child = tree.getChild(i);
switch (child.getType()) {
case DECLARE:
processDeclare(child);
break;
case SELECT:
select = processSelect(child);
break;
case WHERE:
where = processWhere(child);
break;
default:
throw new HL7QueryParsingException("Found unexpected clause at root level: " + tree.getText());
}
}
this.whereEvaluator = where;
this.selections = select;
}
private void processDeclare(final Tree declare) {
for (int i=0; i < declare.getChildCount(); i++) {
final Tree declarationTree = declare.getChild(i);
final String identifier = declarationTree.getChild(0).getText();
final Tree requiredOrOptionalTree = declarationTree.getChild(1);
final boolean required = requiredOrOptionalTree.getType() == REQUIRED;
final String segmentName = declarationTree.getChild(2).getText();
final Declaration declaration = new Declaration() {
@Override
public String getAlias() {
return identifier;
}
@Override
public boolean isRequired() {
return required;
}
@Override
public Object getDeclaredValue(final HL7Message message) {
if ( message == null ) {
return null;
}
return message.getSegments(segmentName);
}
};
declarations.add(declaration);
}
}
private List<Selection> processSelect(final Tree select) {
final List<Selection> selections = new ArrayList<>();
for (int i=0; i < select.getChildCount(); i++) {
final Tree selectable = select.getChild(i);
final String alias = getSelectedName(selectable);
final Evaluator<?> selectionEvaluator = buildReferenceEvaluator(selectable);
final Selection selection = new Selection(selectionEvaluator, alias);
selections.add(selection);
}
return selections;
}
private String getSelectedName(final Tree selectable) {
if ( selectable.getChildCount() == 0 ) {
return selectable.getText();
} else if (selectable.getType() == DOT ) {
return getSelectedName(selectable.getChild(0)) + "." + getSelectedName(selectable.getChild(1));
} else {
return selectable.getChild(selectable.getChildCount() - 1).getText();
}
}
private BooleanEvaluator processWhere(final Tree where) {
return buildBooleanEvaluator(where.getChild(0));
}
private Evaluator<?> buildReferenceEvaluator(final Tree tree) {
switch (tree.getType()) {
case MESSAGE:
return new MessageEvaluator();
case SEGMENT_NAME:
return new SegmentEvaluator(new StringLiteralEvaluator(tree.getText()));
case IDENTIFIER:
return new DeclaredReferenceEvaluator(new StringLiteralEvaluator(tree.getText()));
case DOT:
final Tree firstChild = tree.getChild(0);
final Tree secondChild = tree.getChild(1);
return new DotEvaluator(buildReferenceEvaluator(firstChild), buildIntegerEvaluator(secondChild));
case STRING_LITERAL:
return new StringLiteralEvaluator(tree.getText());
case NUMBER:
return new IntegerLiteralEvaluator(Integer.parseInt(tree.getText()));
default:
throw new HL7QueryParsingException("Failed to build evaluator for " + tree.getText());
}
}
private IntegerEvaluator buildIntegerEvaluator(final Tree tree) {
switch (tree.getType()) {
case NUMBER:
return new IntegerLiteralEvaluator(Integer.parseInt(tree.getText()));
default:
throw new HL7QueryParsingException("Failed to build Integer Evaluator for " + tree.getText());
}
}
private BooleanEvaluator buildBooleanEvaluator(final Tree tree) {
// TODO: add Date comparisons
// LT/GT/GE/GE should allow for dates based on Field's Type
// BETWEEN
// DATE('2015/01/01')
// DATE('2015/01/01 12:00:00')
// DATE('24 HOURS AGO')
// DATE('YESTERDAY')
switch (tree.getType()) {
case EQUALS:
return new EqualsEvaluator(buildReferenceEvaluator(tree.getChild(0)), buildReferenceEvaluator(tree.getChild(1)));
case NOT_EQUALS:
return new NotEqualsEvaluator(buildReferenceEvaluator(tree.getChild(0)), buildReferenceEvaluator(tree.getChild(1)));
case GT:
return new GreaterThanEvaluator(buildReferenceEvaluator(tree.getChild(0)), buildReferenceEvaluator(tree.getChild(1)));
case LT:
return new LessThanEvaluator(buildReferenceEvaluator(tree.getChild(0)), buildReferenceEvaluator(tree.getChild(1)));
case GE:
return new GreaterThanOrEqualEvaluator(buildReferenceEvaluator(tree.getChild(0)), buildReferenceEvaluator(tree.getChild(1)));
case LE:
return new LessThanOrEqualEvaluator(buildReferenceEvaluator(tree.getChild(0)), buildReferenceEvaluator(tree.getChild(1)));
case NOT:
return new NotEvaluator(buildBooleanEvaluator(tree.getChild(0)));
case AND:
return new AndEvaluator(buildBooleanEvaluator(tree.getChild(0)), buildBooleanEvaluator(tree.getChild(1)));
case OR:
return new OrEvaluator(buildBooleanEvaluator(tree.getChild(0)), buildBooleanEvaluator(tree.getChild(1)));
case IS_NULL:
return new IsNullEvaluator(buildReferenceEvaluator(tree.getChild(0)));
case NOT_NULL:
return new NotNullEvaluator(buildReferenceEvaluator(tree.getChild(0)));
default:
throw new HL7QueryParsingException("Cannot build boolean evaluator for '" + tree.getText() + "'");
}
}
Tree getTree() {
return tree;
}
public String getQuery() {
return query;
}
@Override
public String toString() {
return "HL7Query[" + query + "]";
}
public static HL7Query compile(final String query) {
try {
final CommonTokenStream lexerTokenStream = createTokenStream(query);
final HL7QueryParser parser = new HL7QueryParser(lexerTokenStream);
final Tree tree = (Tree) parser.query().getTree();
return new HL7Query(tree, query);
} catch (final HL7QueryParsingException e) {
throw e;
} catch (final Exception e) {
throw new HL7QueryParsingException(e);
}
}
private static CommonTokenStream createTokenStream(final String expression) throws HL7QueryParsingException {
final CharStream input = new ANTLRStringStream(expression);
final HL7QueryLexer lexer = new HL7QueryLexer(input);
return new CommonTokenStream(lexer);
}
public List<Class<?>> getReturnTypes() {
final List<Class<?>> returnTypes = new ArrayList<>();
for ( final Selection selection : selections ) {
returnTypes.add( selection.getEvaluator().getType() );
}
return returnTypes;
}
@SuppressWarnings("unchecked")
public QueryResult evaluate(final HL7Message message) {
int totalIterations = 1;
final LinkedHashMap<String, List<Object>> possibleValueMap = new LinkedHashMap<>();
for ( final Declaration declaration : declarations ) {
final Object value = declaration.getDeclaredValue(message);
if ( value == null && declaration.isRequired() ) {
return new MissedResult(selections);
}
final List<Object> possibleValues;
if ( value instanceof List ) {
possibleValues = (List<Object>) value;
} else if ( value instanceof Collection ) {
possibleValues = new ArrayList<Object>((Collection<Object>) value);
} else {
possibleValues = new ArrayList<>(1);
possibleValues.add(value);
}
if ( possibleValues.isEmpty() ) {
return new MissedResult(selections);
}
possibleValueMap.put(declaration.getAlias(), possibleValues);
totalIterations *= possibleValues.size();
}
final Set<Map<String, Object>> resultSet = new HashSet<>();
for (int i=0; i < totalIterations; i++) {
final Map<String, Object> aliasValues = assignAliases(possibleValueMap, i);
aliasValues.put(Evaluator.MESSAGE_KEY, message);
if (whereEvaluator == null || Boolean.TRUE.equals(whereEvaluator.evaluate(aliasValues))) {
final Map<String, Object> resultMap = new HashMap<>();
for ( final Selection selection : selections ) {
final Object value = selection.getEvaluator().evaluate(aliasValues);
resultMap.put(selection.getName(), value);
}
resultSet.add(resultMap);
}
}
// for ( final Declaration declaration : declarations ) {
// final Object value = declaration.getDeclaredValue(message);
// if ( value == null && declaration.isRequired() ) {
// return new MissedResult(selections);
// }
// objectMap.put(declaration.getAlias(), value);
// }
//
// if (whereEvaluator == null || Boolean.TRUE.equals(whereEvaluator.evaluate(objectMap))) {
// for ( final Selection selection : selections ) {
// final Object value = selection.getEvaluator().evaluate(objectMap);
// resultMap.put(selection.getName(), value);
// }
// } else {
// return new MissedResult(selections);
// }
return new StandardQueryResult(selections, resultSet);
}
// assigns one of the possible values to each alias, based on which iteration this is.
// require LinkedHashMap just to be very clear and explicit that the order of the Map MUST be guaranteed
// between multiple invocations of this method.
// package protected for testing visibility
// static Map<String, Object> assignAliases(final LinkedHashMap<String, List<Object>> possibleValues, final int iteration) {
// final Map<String, Object> aliasMap = new HashMap<>();
//
// int aliasIndex = possibleValues.size() - 1;
// for ( final Map.Entry<String, List<Object>> entry : possibleValues.entrySet() ) {
// final String alias = entry.getKey();
// final List<Object> validValues = entry.getValue();
//
// final int validValueIndex;
// if (aliasIndex > 0) {
// validValueIndex = iteration / aliasIndex;
// } else {
// validValueIndex = iteration;
// }
//
// final Object obj = validValues.get(validValueIndex % validValues.size());
// aliasMap.put(alias, obj);
//
// aliasIndex--;
// }
//
// return aliasMap;
// }
//
static Map<String, Object> assignAliases(final LinkedHashMap<String, List<Object>> possibleValues, final int iteration) {
final Map<String, Object> aliasMap = new HashMap<>();
int divisor = 1;
for ( final Map.Entry<String, List<Object>> entry : possibleValues.entrySet() ) {
final String alias = entry.getKey();
final List<Object> validValues = entry.getValue();
final int idx = (iteration / divisor) % validValues.size();
final Object obj = validValues.get(idx);
aliasMap.put(alias, obj);
divisor *= validValues.size();
}
return aliasMap;
}
public String toTreeString() {
final StringBuilder sb = new StringBuilder();
toTreeString(tree, sb, 0);
return sb.toString();
}
private void toTreeString(final Tree tree, final StringBuilder sb, final int indentLevel) {
final String nodeName = tree.getText();
for (int i=0; i < indentLevel; i++) {
sb.append(" ");
}
sb.append(nodeName);
sb.append("\n");
for (int i=0; i < tree.getChildCount(); i++) {
final Tree child = tree.getChild(i);
toTreeString(child, sb, indentLevel + 2);
}
}
}

View File

@ -0,0 +1,29 @@
/*
* 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.nifi.hl7.query;
import java.util.List;
public interface QueryResult {
boolean isMatch();
List<String> getLabels();
int getHitCount();
ResultHit nextHit();
}

View File

@ -0,0 +1,25 @@
/*
* 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.nifi.hl7.query;
import java.util.Map;
public interface ResultHit {
Object getValue(String label);
Map<String, Object> getSelectedValues();
}

View File

@ -0,0 +1,37 @@
/*
* 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.nifi.hl7.query;
import org.apache.nifi.hl7.query.evaluator.Evaluator;
public class Selection {
private final Evaluator<?> evaluator;
private final String name;
public Selection(final Evaluator<?> evaluator, final String name) {
this.evaluator = evaluator;
this.name = name;
}
public String getName() {
return name;
}
public Evaluator<?> getEvaluator() {
return evaluator;
}
}

View File

@ -0,0 +1,24 @@
/*
* 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.nifi.hl7.query.evaluator;
public abstract class BooleanEvaluator implements Evaluator<Boolean> {
public Class<? extends Boolean> getType() {
return Boolean.class;
}
}

View File

@ -0,0 +1,27 @@
/*
* 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.nifi.hl7.query.evaluator;
import java.util.Map;
public interface Evaluator<T> {
public static final String MESSAGE_KEY = "message";
T evaluate(Map<String, Object> objectMap);
Class<? extends T> getType();
}

View File

@ -0,0 +1,26 @@
/*
* 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.nifi.hl7.query.evaluator;
public abstract class IntegerEvaluator implements Evaluator<Integer> {
public Class<? extends Integer> getType() {
return Integer.class;
}
}

View File

@ -0,0 +1,25 @@
/*
* 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.nifi.hl7.query.evaluator;
public abstract class StringEvaluator implements Evaluator<String> {
public Class<? extends String> getType() {
return String.class;
}
}

View File

@ -0,0 +1,106 @@
/*
* 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.nifi.hl7.query.evaluator.comparison;
import java.util.Collection;
import java.util.Map;
import org.apache.nifi.hl7.model.HL7Field;
import org.apache.nifi.hl7.query.evaluator.BooleanEvaluator;
import org.apache.nifi.hl7.query.evaluator.Evaluator;
public abstract class AbstractComparisonEvaluator extends BooleanEvaluator {
private final Evaluator<?> lhs;
private final Evaluator<?> rhs;
public AbstractComparisonEvaluator(final Evaluator<?> lhs, final Evaluator<?> rhs) {
this.lhs = lhs;
this.rhs = rhs;
}
public final Boolean evaluate(final Map<String, Object> objectMap) {
final Object lhsValue = lhs.evaluate(objectMap);
if ( lhsValue == null ) {
return false;
}
final Object rhsValue = rhs.evaluate(objectMap);
if ( rhsValue == null ) {
return false;
}
return compareRaw(lhsValue, rhsValue);
}
private Boolean compareRaw(Object lhsValue, Object rhsValue) {
if ( lhsValue == null || rhsValue == null ) {
return false;
}
if ( lhsValue instanceof HL7Field ) {
lhsValue = ((HL7Field) lhsValue).getValue();
}
if ( rhsValue instanceof HL7Field ) {
rhsValue = ((HL7Field) rhsValue).getValue();
}
if ( lhsValue == null || rhsValue == null ) {
return false;
}
// both are collections, and compare(lhsValue, rhsValue) is false.
// this would be the case, for instance, if we compared field 1 of one segment to
// a field in another segment, and both fields had components.
if ( lhsValue instanceof Collection && rhsValue instanceof Collection ) {
return false;
}
// if one side is a collection but the other is not, check if any element in that
// collection compares to the other element in a way that satisfies the condition.
// this would happen, for instance, if we check Segment1.Field5 = 'X' and field 5 repeats
// with a value "A~B~C~X~Y~Z"; in this case we do want to consider Field 5 = X as true.
if ( lhsValue instanceof Collection ) {
for ( final Object lhsObject : (Collection<?>) lhsValue ) {
if ( compareRaw(lhsObject, rhsValue) ) {
return true;
}
}
return false;
}
if ( rhsValue instanceof Collection ) {
for ( final Object rhsObject : (Collection<?>) rhsValue ) {
if ( compareRaw(rhsObject, lhsValue) ) {
return true;
}
}
return false;
}
if ( lhsValue != null && rhsValue != null && compare(lhsValue, rhsValue) ) {
return true;
}
return false;
}
protected abstract boolean compare(Object lhs, Object rhs);
}

View File

@ -0,0 +1,67 @@
/*
* 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.nifi.hl7.query.evaluator.comparison;
import java.util.regex.Pattern;
import org.apache.nifi.hl7.query.evaluator.Evaluator;
public abstract class AbstractNumericComparison extends AbstractComparisonEvaluator {
private static final Pattern NUMERIC_PATTERN = Pattern.compile("\\d+(\\.\\d+)?");
public AbstractNumericComparison(final Evaluator<?> lhs, final Evaluator<?> rhs) {
super(lhs, rhs);
}
@Override
protected final boolean compare(final Object lhs, final Object rhs) {
final Double lhsDouble = toDouble(lhs);
if ( lhsDouble == null ) {
return false;
}
final Double rhsDouble = toDouble(rhs);
if ( rhsDouble == null ) {
return false;
}
return compareNumbers(lhsDouble, rhsDouble);
}
private Double toDouble(final Object value) {
if ( value == null ) {
return null;
}
if ( value instanceof Double ) {
return (Double) value;
}
if ( value instanceof Number ) {
return ((Number) value).doubleValue();
}
if ( value instanceof String ) {
if ( NUMERIC_PATTERN.matcher((String) value).matches() ) {
return Double.parseDouble((String) value);
}
}
return null;
}
protected abstract boolean compareNumbers(final Double lhs, final Double rhs);
}

View File

@ -0,0 +1,32 @@
/*
* 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.nifi.hl7.query.evaluator.comparison;
import org.apache.nifi.hl7.query.evaluator.Evaluator;
public class EqualsEvaluator extends AbstractComparisonEvaluator {
public EqualsEvaluator(final Evaluator<?> lhs, final Evaluator<?> rhs) {
super(lhs, rhs);
}
@Override
protected boolean compare(final Object lhs, final Object rhs) {
return lhs != null && rhs != null && ((lhs == rhs) || (lhs.equals(rhs)) || lhs.toString().equals(rhs.toString()));
}
}

View File

@ -0,0 +1,34 @@
/*
* 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.nifi.hl7.query.evaluator.comparison;
import org.apache.nifi.hl7.query.evaluator.Evaluator;
public class GreaterThanEvaluator extends AbstractNumericComparison {
public GreaterThanEvaluator(final Evaluator<?> lhs, final Evaluator<?> rhs) {
super(lhs, rhs);
}
@Override
protected boolean compareNumbers(final Double lhs, final Double rhs) {
return lhs > rhs;
}
}

View File

@ -0,0 +1,34 @@
/*
* 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.nifi.hl7.query.evaluator.comparison;
import org.apache.nifi.hl7.query.evaluator.Evaluator;
public class GreaterThanOrEqualEvaluator extends AbstractNumericComparison {
public GreaterThanOrEqualEvaluator(final Evaluator<?> lhs, final Evaluator<?> rhs) {
super(lhs, rhs);
}
@Override
protected boolean compareNumbers(final Double lhs, final Double rhs) {
return lhs >= rhs;
}
}

View File

@ -0,0 +1,69 @@
/*
* 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.nifi.hl7.query.evaluator.comparison;
import java.util.Collection;
import java.util.Map;
import org.apache.nifi.hl7.model.HL7Component;
import org.apache.nifi.hl7.query.evaluator.BooleanEvaluator;
import org.apache.nifi.hl7.query.evaluator.Evaluator;
public class IsNullEvaluator extends BooleanEvaluator {
private final Evaluator<?> subjectEvaluator;
public IsNullEvaluator(final Evaluator<?> subjectEvaluator) {
this.subjectEvaluator = subjectEvaluator;
}
@Override
public Boolean evaluate(final Map<String, Object> objectMap) {
Object subjectValue = subjectEvaluator.evaluate(objectMap);
if ( subjectValue == null ) {
return true;
}
return isNull(subjectValue);
}
private boolean isNull(Object subjectValue) {
if ( subjectValue == null ) {
return true;
}
if ( subjectValue instanceof HL7Component ) {
subjectValue = ((HL7Component) subjectValue).getValue();
}
if ( subjectValue instanceof Collection ) {
final Collection<?> collection = (Collection<?>) subjectValue;
if ( collection.isEmpty() ) {
return true;
}
for ( final Object obj : collection ) {
if ( !isNull(obj) ) {
return false;
}
}
return true;
}
return subjectValue == null;
}
}

View File

@ -0,0 +1,31 @@
/*
* 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.nifi.hl7.query.evaluator.comparison;
import org.apache.nifi.hl7.query.evaluator.Evaluator;
public class LessThanEvaluator extends AbstractNumericComparison {
public LessThanEvaluator(final Evaluator<?> lhs, final Evaluator<?> rhs) {
super(lhs, rhs);
}
@Override
protected boolean compareNumbers(final Double lhs, final Double rhs) {
return lhs < rhs;
}
}

View File

@ -0,0 +1,31 @@
/*
* 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.nifi.hl7.query.evaluator.comparison;
import org.apache.nifi.hl7.query.evaluator.Evaluator;
public class LessThanOrEqualEvaluator extends AbstractNumericComparison {
public LessThanOrEqualEvaluator(final Evaluator<?> lhs, final Evaluator<?> rhs) {
super(lhs, rhs);
}
@Override
protected boolean compareNumbers(final Double lhs, final Double rhs) {
return lhs <= rhs;
}
}

View File

@ -0,0 +1,32 @@
/*
* 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.nifi.hl7.query.evaluator.comparison;
import org.apache.nifi.hl7.query.evaluator.Evaluator;
public class NotEqualsEvaluator extends AbstractComparisonEvaluator {
public NotEqualsEvaluator(final Evaluator<?> lhs, final Evaluator<?> rhs) {
super(lhs, rhs);
}
@Override
protected boolean compare(final Object lhs, final Object rhs) {
return lhs != null && rhs != null && lhs != rhs && !lhs.equals(rhs) && !lhs.toString().equals(rhs.toString());
}
}

View File

@ -0,0 +1,36 @@
/*
* 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.nifi.hl7.query.evaluator.comparison;
import java.util.Map;
import org.apache.nifi.hl7.query.evaluator.BooleanEvaluator;
public class NotEvaluator extends BooleanEvaluator {
private final BooleanEvaluator subjectEvaluator;
public NotEvaluator(final BooleanEvaluator subjectEvaluator) {
this.subjectEvaluator = subjectEvaluator;
}
@Override
public Boolean evaluate(final Map<String, Object> objectMap) {
final Boolean subjectValue = subjectEvaluator.evaluate(objectMap);
return (subjectValue == null || Boolean.TRUE.equals(subjectValue));
}
}

View File

@ -0,0 +1,65 @@
/*
* 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.nifi.hl7.query.evaluator.comparison;
import java.util.Collection;
import java.util.Map;
import org.apache.nifi.hl7.model.HL7Component;
import org.apache.nifi.hl7.query.evaluator.BooleanEvaluator;
import org.apache.nifi.hl7.query.evaluator.Evaluator;
public class NotNullEvaluator extends BooleanEvaluator {
private final Evaluator<?> subjectEvaluator;
public NotNullEvaluator(final Evaluator<?> subjectEvaluator) {
this.subjectEvaluator = subjectEvaluator;
}
@Override
public Boolean evaluate(final Map<String, Object> objectMap) {
Object subjectValue = subjectEvaluator.evaluate(objectMap);
if ( subjectValue == null ) {
return false;
}
return isNotNull(subjectValue);
}
private boolean isNotNull(Object subjectValue) {
if ( subjectValue instanceof HL7Component ) {
subjectValue = ((HL7Component) subjectValue).getValue();
}
if ( subjectValue instanceof Collection ) {
final Collection<?> collection = (Collection<?>) subjectValue;
if ( collection.isEmpty() ) {
return false;
}
for ( final Object obj : collection ) {
if ( isNotNull(obj) ) {
return true;
}
}
return false;
}
return subjectValue != null;
}
}

View File

@ -0,0 +1,36 @@
/*
* 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.nifi.hl7.query.evaluator.literal;
import java.util.Map;
import org.apache.nifi.hl7.query.evaluator.IntegerEvaluator;
public class IntegerLiteralEvaluator extends IntegerEvaluator {
private final Integer value;
public IntegerLiteralEvaluator(final Integer value) {
this.value = value;
}
@Override
public Integer evaluate(final Map<String, Object> objectMap) {
return value;
}
}

View File

@ -0,0 +1,35 @@
/*
* 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.nifi.hl7.query.evaluator.literal;
import java.util.Map;
import org.apache.nifi.hl7.query.evaluator.StringEvaluator;
public class StringLiteralEvaluator extends StringEvaluator {
private final String value;
public StringLiteralEvaluator(final String value) {
this.value = value;
}
@Override
public String evaluate(final Map<String, Object> objectMap) {
return value;
}
}

View File

@ -0,0 +1,43 @@
/*
* 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.nifi.hl7.query.evaluator.logic;
import java.util.Map;
import org.apache.nifi.hl7.query.evaluator.BooleanEvaluator;
public class AndEvaluator extends BooleanEvaluator {
private final BooleanEvaluator lhs;
private final BooleanEvaluator rhs;
public AndEvaluator(final BooleanEvaluator lhs, final BooleanEvaluator rhs) {
this.lhs = lhs;
this.rhs = rhs;
}
@Override
public Boolean evaluate(final Map<String, Object> objectMap) {
final Boolean lhsValue = lhs.evaluate(objectMap);
if ( lhsValue == null || Boolean.FALSE.equals(lhsValue) ) {
return false;
}
final Boolean rhsValue = rhs.evaluate(objectMap);
return (rhsValue != null && Boolean.TRUE.equals(rhsValue));
}
}

View File

@ -0,0 +1,43 @@
/*
* 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.nifi.hl7.query.evaluator.logic;
import java.util.Map;
import org.apache.nifi.hl7.query.evaluator.BooleanEvaluator;
public class OrEvaluator extends BooleanEvaluator {
private final BooleanEvaluator lhs;
private final BooleanEvaluator rhs;
public OrEvaluator(final BooleanEvaluator lhs, final BooleanEvaluator rhs) {
this.lhs = lhs;
this.rhs = rhs;
}
@Override
public Boolean evaluate(final Map<String, Object> objectMap) {
final Boolean lhsValue = lhs.evaluate(objectMap);
if ( lhsValue != null && Boolean.TRUE.equals(lhsValue) ) {
return true;
}
final Boolean rhsValue = rhs.evaluate(objectMap);
return (rhsValue != null && Boolean.TRUE.equals(rhsValue));
}
}

View File

@ -0,0 +1,42 @@
/*
* 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.nifi.hl7.query.evaluator.message;
import java.util.Map;
import org.apache.nifi.hl7.query.evaluator.Evaluator;
import org.apache.nifi.hl7.query.evaluator.StringEvaluator;
public class DeclaredReferenceEvaluator implements Evaluator<Object> {
private final StringEvaluator referenceNameEvaluator;
public DeclaredReferenceEvaluator(final StringEvaluator referenceNameEvaluator) {
this.referenceNameEvaluator = referenceNameEvaluator;
}
@Override
public Object evaluate(final Map<String, Object> objectMap) {
final String referenceName = referenceNameEvaluator.evaluate(objectMap);
return objectMap.get(referenceName);
}
@Override
public Class<? extends Object> getType() {
return Object.class;
}
}

View File

@ -0,0 +1,88 @@
/*
* 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.nifi.hl7.query.evaluator.message;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import org.apache.nifi.hl7.model.HL7Component;
import org.apache.nifi.hl7.model.HL7Message;
import org.apache.nifi.hl7.model.HL7Segment;
import org.apache.nifi.hl7.query.evaluator.Evaluator;
import org.apache.nifi.hl7.query.evaluator.IntegerEvaluator;
public class DotEvaluator implements Evaluator<Object> {
private final Evaluator<?> lhs;
private final IntegerEvaluator rhs;
public DotEvaluator(final Evaluator<?> lhs, final IntegerEvaluator rhs) {
this.lhs = lhs;
this.rhs = rhs;
}
@Override
public Object evaluate(final Map<String, Object> objectMap) {
final Object lhsValue = this.lhs.evaluate(objectMap);
final Integer rhsValue = this.rhs.evaluate(objectMap);
if ( lhsValue == null || rhsValue == null ) {
return null;
}
final List<Object> results = new ArrayList<>();
if ( lhsValue instanceof Collection ) {
final Collection<?> lhsCollection = (Collection<?>) lhsValue;
for ( final Object obj : lhsCollection ) {
final Object val = getValue(obj, rhsValue);
results.add(val);
}
} else {
final Object val = getValue(lhsValue, rhsValue);
return val;
}
return results;
}
private Object getValue(final Object lhsValue, final int rhsValue) {
final List<?> list;
if ( lhsValue instanceof HL7Message ) {
list = ((HL7Message) lhsValue).getSegments();
} else if ( lhsValue instanceof HL7Segment ) {
list = ((HL7Segment) lhsValue).getFields();
} else if ( lhsValue instanceof HL7Component ) {
list = ((HL7Component) lhsValue).getComponents();
} else {
return null;
}
if ( rhsValue > list.size() ) {
return null;
}
// convert from 0-based to 1-based
return list.get(rhsValue - 1);
}
@Override
public Class<? extends Object> getType() {
return Object.class;
}
}

View File

@ -0,0 +1,67 @@
/*
* 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.nifi.hl7.query.evaluator.message;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import org.apache.nifi.hl7.model.HL7Field;
import org.apache.nifi.hl7.model.HL7Segment;
import org.apache.nifi.hl7.query.evaluator.Evaluator;
import org.apache.nifi.hl7.query.evaluator.IntegerEvaluator;
@SuppressWarnings("rawtypes")
public class FieldEvaluator implements Evaluator<List> {
private final SegmentEvaluator segmentEvaluator;
private final IntegerEvaluator indexEvaluator;
public FieldEvaluator(final SegmentEvaluator segmentEvaluator, final IntegerEvaluator indexEvaluator) {
this.segmentEvaluator = segmentEvaluator;
this.indexEvaluator = indexEvaluator;
}
public List<HL7Field> evaluate(final Map<String, Object> objectMap) {
final List<HL7Segment> segments = segmentEvaluator.evaluate(objectMap);
if ( segments == null ) {
return Collections.emptyList();
}
final Integer index = indexEvaluator.evaluate(objectMap);
if ( index == null ) {
return Collections.emptyList();
}
final List<HL7Field> fields = new ArrayList<>();
for ( final HL7Segment segment : segments ) {
final List<HL7Field> segmentFields = segment.getFields();
if ( segmentFields.size() <= index ) {
continue;
}
fields.add(segmentFields.get(index));
}
return fields;
}
public Class<? extends List> getType() {
return List.class;
}
}

View File

@ -0,0 +1,34 @@
/*
* 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.nifi.hl7.query.evaluator.message;
import java.util.Map;
import org.apache.nifi.hl7.model.HL7Message;
import org.apache.nifi.hl7.query.evaluator.Evaluator;
public class MessageEvaluator implements Evaluator<HL7Message> {
public HL7Message evaluate(final Map<String, Object> objectMap) {
return (HL7Message) objectMap.get(Evaluator.MESSAGE_KEY);
}
public Class<? extends HL7Message> getType() {
return HL7Message.class;
}
}

View File

@ -0,0 +1,51 @@
/*
* 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.nifi.hl7.query.evaluator.message;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import org.apache.nifi.hl7.model.HL7Message;
import org.apache.nifi.hl7.model.HL7Segment;
import org.apache.nifi.hl7.query.evaluator.Evaluator;
import org.apache.nifi.hl7.query.evaluator.StringEvaluator;
@SuppressWarnings("rawtypes")
public class SegmentEvaluator implements Evaluator<List> {
private final StringEvaluator segmentTypeEvaluator;
public SegmentEvaluator(final StringEvaluator segmentTypeEvaluator) {
this.segmentTypeEvaluator = segmentTypeEvaluator;
}
public List<HL7Segment> evaluate(final Map<String, Object> objectMap) {
final String segmentType = segmentTypeEvaluator.evaluate(objectMap);
if ( segmentType == null ) {
return Collections.emptyList();
}
final HL7Message message = (HL7Message) objectMap.get(Evaluator.MESSAGE_KEY);
final List<HL7Segment> segments = message.getSegments(segmentType);
return (segments == null) ? Collections.<HL7Segment>emptyList() : segments;
}
public Class<? extends List> getType() {
return List.class;
}
}

View File

@ -0,0 +1,37 @@
/*
* 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.nifi.hl7.query.exception;
public class HL7QueryParsingException extends RuntimeException {
private static final long serialVersionUID = 1L;
public HL7QueryParsingException() {
super();
}
public HL7QueryParsingException(final Throwable cause) {
super(cause);
}
public HL7QueryParsingException(final String message) {
super(message);
}
public HL7QueryParsingException(final String message, final Throwable cause) {
super(message, cause);
}
}

View File

@ -0,0 +1,56 @@
/*
* 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.nifi.hl7.query.result;
import java.util.ArrayList;
import java.util.List;
import org.apache.nifi.hl7.query.QueryResult;
import org.apache.nifi.hl7.query.ResultHit;
import org.apache.nifi.hl7.query.Selection;
public class MissedResult implements QueryResult {
private final List<Selection> selections;
public MissedResult(final List<Selection> selections) {
this.selections = selections;
}
@Override
public List<String> getLabels() {
final List<String> labels = new ArrayList<>();
for ( final Selection selection : selections ) {
labels.add(selection.getName());
}
return labels;
}
@Override
public boolean isMatch() {
return false;
}
@Override
public ResultHit nextHit() {
return null;
}
@Override
public int getHitCount() {
return 0;
}
}

View File

@ -0,0 +1,69 @@
/*
* 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.nifi.hl7.query.result;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.nifi.hl7.query.QueryResult;
import org.apache.nifi.hl7.query.ResultHit;
import org.apache.nifi.hl7.query.Selection;
public class StandardQueryResult implements QueryResult {
private final List<Selection> selections;
private final Set<Map<String, Object>> hits;
private final Iterator<Map<String, Object>> hitIterator;
public StandardQueryResult(final List<Selection> selections, final Set<Map<String, Object>> hits) {
this.selections = selections;
this.hits = hits;
hitIterator = hits.iterator();
}
@Override
public boolean isMatch() {
return !hits.isEmpty();
}
@Override
public List<String> getLabels() {
final List<String> labels = new ArrayList<>();
for ( final Selection selection : selections ) {
labels.add(selection.getName());
}
return labels;
}
@Override
public int getHitCount() {
return hits.size();
}
@Override
public ResultHit nextHit() {
if ( hitIterator.hasNext() ) {
return new StandardResultHit(hitIterator.next());
} else {
return null;
}
}
}

View File

@ -0,0 +1,41 @@
/*
* 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.nifi.hl7.query.result;
import java.util.Collections;
import java.util.Map;
import org.apache.nifi.hl7.query.ResultHit;
public class StandardResultHit implements ResultHit {
private final Map<String, Object> values;
public StandardResultHit(final Map<String, Object> values) {
this.values = values;
}
@Override
public Object getValue(final String label) {
return values.get(label);
}
@Override
public Map<String, Object> getSelectedValues() {
return Collections.unmodifiableMap(values);
}
}

View File

@ -0,0 +1,352 @@
/*
* 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.nifi.hl7.query;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.apache.nifi.hl7.hapi.HapiMessage;
import org.apache.nifi.hl7.model.HL7Field;
import org.apache.nifi.hl7.model.HL7Message;
import org.apache.nifi.hl7.query.HL7Query;
import org.apache.nifi.hl7.query.QueryResult;
import org.junit.Test;
import ca.uhn.hl7v2.DefaultHapiContext;
import ca.uhn.hl7v2.HL7Exception;
import ca.uhn.hl7v2.HapiContext;
import ca.uhn.hl7v2.model.Message;
import ca.uhn.hl7v2.parser.PipeParser;
import ca.uhn.hl7v2.validation.impl.ValidationContextFactory;
@SuppressWarnings("resource")
public class TestHL7Query {
@Test
public void testAssignAliases() {
final LinkedHashMap<String, List<Object>> possibleValueMap = new LinkedHashMap<>();
final List<Object> valuesA = new ArrayList<>();
valuesA.add("a");
valuesA.add("b");
valuesA.add("c");
final List<Object> valuesB = new ArrayList<>();
valuesB.add("d");
final List<Object> valuesC = new ArrayList<>();
valuesC.add("e");
valuesC.add("f");
final List<Object> valuesD = new ArrayList<>();
valuesD.add("g");
valuesD.add("h");
possibleValueMap.put("A", valuesA);
possibleValueMap.put("B", valuesB);
possibleValueMap.put("C", valuesC);
possibleValueMap.put("D", valuesD);
for (int i=0; i < valuesA.size() * valuesB.size() * valuesC.size() * valuesD.size(); i++) {
System.out.println(i + " : " + HL7Query.assignAliases(possibleValueMap, i));
}
verifyAssignments(HL7Query.assignAliases(possibleValueMap, 0), "a", "d", "e", "g");
verifyAssignments(HL7Query.assignAliases(possibleValueMap, 1), "b", "d", "e", "g");
verifyAssignments(HL7Query.assignAliases(possibleValueMap, 2), "c", "d", "e", "g");
verifyAssignments(HL7Query.assignAliases(possibleValueMap, 3), "a", "d", "f", "g");
verifyAssignments(HL7Query.assignAliases(possibleValueMap, 4), "b", "d", "f", "g");
verifyAssignments(HL7Query.assignAliases(possibleValueMap, 5), "c", "d", "f", "g");
verifyAssignments(HL7Query.assignAliases(possibleValueMap, 6), "a", "d", "e", "h");
verifyAssignments(HL7Query.assignAliases(possibleValueMap, 7), "b", "d", "e", "h");
verifyAssignments(HL7Query.assignAliases(possibleValueMap, 8), "c", "d", "e", "h");
verifyAssignments(HL7Query.assignAliases(possibleValueMap, 9), "a", "d", "f", "h");
verifyAssignments(HL7Query.assignAliases(possibleValueMap, 10), "b", "d", "f", "h");
verifyAssignments(HL7Query.assignAliases(possibleValueMap, 11), "c", "d", "f", "h");
}
private void verifyAssignments(final Map<String, Object> map, final String a, final String b, final String c, final String d) {
assertEquals(a, map.get("A"));
assertEquals(b, map.get("B"));
assertEquals(c, map.get("C"));
assertEquals(d, map.get("D"));
}
@Test
public void testSelectMessage() throws HL7Exception, IOException {
final HL7Query query = HL7Query.compile("SELECT MESSAGE");
final HL7Message msg = createMessage(new File("src/test/resources/vaers-message-long"));
final QueryResult result = query.evaluate(msg);
assertTrue(result.isMatch());
final List<String> labels = result.getLabels();
assertEquals(1, labels.size());
assertEquals("MESSAGE", labels.get(0));
assertEquals(1, result.getHitCount());
assertEquals(msg, result.nextHit().getValue("MESSAGE"));
}
@Test
@SuppressWarnings({ "unchecked", "rawtypes" })
public void testSelectField() throws HL7Exception, IOException {
final HL7Query query = HL7Query.compile("SELECT PID.5");
final HL7Message msg = createMessage(new File("src/test/resources/unsolicited-vaccine-update-short"));
final QueryResult result = query.evaluate(msg);
assertTrue(result.isMatch());
final List<String> labels = result.getLabels();
assertEquals(1, labels.size());
assertEquals(1, result.getHitCount());
final Object names = result.nextHit().getValue("PID.5");
assertTrue(names instanceof List);
final List<Object> nameList = (List) names;
assertEquals(1, nameList.size());
final HL7Field nameField = (HL7Field) nameList.get(0);
assertEquals("KENNEDY^JOHN^FITZGERALD^JR", nameField.getValue());
}
@Test
public void testSelectAbnormalTestResult() throws HL7Exception, IOException {
final String query = "DECLARE result AS REQUIRED OBX SELECT result WHERE result.7 != 'N' AND result.1 = 1";
final HL7Query hl7Query = HL7Query.compile(query);
final QueryResult result = hl7Query.evaluate(createMessage(new File("src/test/resources/vaers-message-long")));
assertFalse( result.isMatch() );
}
@Test
public void testFieldEqualsString() throws HL7Exception, IOException {
HL7Query hl7Query = HL7Query.compile("DECLARE result AS REQUIRED OBX SELECT MESSAGE WHERE result.7 = 'L'");
QueryResult result = hl7Query.evaluate(createMessage(new File("src/test/resources/hypoglycemia")));
assertTrue( result.isMatch() );
hl7Query = HL7Query.compile("DECLARE result AS REQUIRED OBX SELECT MESSAGE WHERE result.7 = 'H'");
result = hl7Query.evaluate(createMessage(new File("src/test/resources/hypoglycemia")));
assertFalse( result.isMatch() );
}
@Test
public void testLessThan() throws HL7Exception, IOException {
HL7Query hl7Query = HL7Query.compile("DECLARE result AS REQUIRED OBX SELECT MESSAGE WHERE result.4 < 600");
QueryResult result = hl7Query.evaluate(createMessage(new File("src/test/resources/hypoglycemia")));
assertTrue( result.isMatch() );
hl7Query = HL7Query.compile("DECLARE result AS REQUIRED OBX SELECT MESSAGE WHERE result.4 < 59");
result = hl7Query.evaluate(createMessage(new File("src/test/resources/hypoglycemia")));
assertFalse( result.isMatch() );
}
@Test
public void testCompareTwoFields() throws HL7Exception, IOException {
HL7Query hl7Query = HL7Query.compile("DECLARE result AS REQUIRED OBX SELECT MESSAGE WHERE result.4 < result.6.2");
QueryResult result = hl7Query.evaluate(createMessage(new File("src/test/resources/hypoglycemia")));
assertTrue( result.isMatch() );
hl7Query = HL7Query.compile("DECLARE result AS REQUIRED OBX SELECT MESSAGE WHERE NOT(result.4 > result.6.3)");
result = hl7Query.evaluate(createMessage(new File("src/test/resources/hypoglycemia")));
assertFalse( result.isMatch() );
}
@Test
public void testLessThanOrEqual() throws HL7Exception, IOException {
HL7Query hl7Query = HL7Query.compile("DECLARE result AS REQUIRED OBX SELECT MESSAGE WHERE result.4 <= 59");
QueryResult result = hl7Query.evaluate(createMessage(new File("src/test/resources/hypoglycemia")));
assertTrue( result.isMatch() );
hl7Query = HL7Query.compile("DECLARE result AS REQUIRED OBX SELECT MESSAGE WHERE result.4 <= 600");
result = hl7Query.evaluate(createMessage(new File("src/test/resources/hypoglycemia")));
assertTrue( result.isMatch() );
hl7Query = HL7Query.compile("DECLARE result AS REQUIRED OBX SELECT MESSAGE WHERE result.4 <= 58");
result = hl7Query.evaluate(createMessage(new File("src/test/resources/hypoglycemia")));
assertFalse( result.isMatch() );
}
@Test
public void testGreaterThanOrEqual() throws HL7Exception, IOException {
HL7Query hl7Query = HL7Query.compile("DECLARE result AS REQUIRED OBX SELECT MESSAGE WHERE result.4 >= 59");
QueryResult result = hl7Query.evaluate(createMessage(new File("src/test/resources/hypoglycemia")));
assertTrue( result.isMatch() );
hl7Query = HL7Query.compile("DECLARE result AS REQUIRED OBX SELECT MESSAGE WHERE result.4 >= 6");
result = hl7Query.evaluate(createMessage(new File("src/test/resources/hypoglycemia")));
assertTrue( result.isMatch() );
hl7Query = HL7Query.compile("DECLARE result AS REQUIRED OBX SELECT MESSAGE WHERE result.4 >= 580");
result = hl7Query.evaluate(createMessage(new File("src/test/resources/hypoglycemia")));
assertFalse( result.isMatch() );
}
@Test
public void testGreaterThan() throws HL7Exception, IOException {
HL7Query hl7Query = HL7Query.compile("DECLARE result AS REQUIRED OBX SELECT MESSAGE WHERE result.4 > 58");
QueryResult result = hl7Query.evaluate(createMessage(new File("src/test/resources/hypoglycemia")));
assertTrue( result.isMatch() );
hl7Query = HL7Query.compile("DECLARE result AS REQUIRED OBX SELECT MESSAGE WHERE result.4 > 6");
result = hl7Query.evaluate(createMessage(new File("src/test/resources/hypoglycemia")));
assertTrue( result.isMatch() );
hl7Query = HL7Query.compile("DECLARE result AS REQUIRED OBX SELECT MESSAGE WHERE result.4 > 580");
result = hl7Query.evaluate(createMessage(new File("src/test/resources/hypoglycemia")));
assertFalse( result.isMatch() );
}
@Test
public void testDistinctValuesReturned() throws HL7Exception, IOException {
HL7Query hl7Query = HL7Query.compile("DECLARE result1 AS REQUIRED OBX, result2 AS REQUIRED OBX SELECT MESSAGE WHERE result1.7 = 'L' OR result2.7 != 'H'");
QueryResult result = hl7Query.evaluate(createMessage(new File("src/test/resources/hypoglycemia")));
assertTrue( result.isMatch() );
assertEquals(1, result.getHitCount());
hl7Query = HL7Query.compile("DECLARE result AS REQUIRED OBX SELECT result WHERE result.1 = 1");
HL7Message msg = createMessage(new File("src/test/resources/vaers-message-long"));
result = hl7Query.evaluate(msg);
assertTrue( result.isMatch() );
assertEquals(9, result.getHitCount());
hl7Query = HL7Query.compile("DECLARE result AS REQUIRED OBX SELECT result WHERE result.1 = 1 AND result.3.1.1 = '30961-7'");
result = hl7Query.evaluate(msg);
assertTrue( result.isMatch() );
assertEquals(1, result.getHitCount());
}
@Test
public void testAndWithParens() throws HL7Exception, IOException {
HL7Query hl7Query = HL7Query.compile("DECLARE result AS REQUIRED OBX SELECT MESSAGE WHERE result.7 = 'L' AND result.3.1 = 'GLU'");
QueryResult result = hl7Query.evaluate(createMessage(new File("src/test/resources/hypoglycemia")));
assertTrue( result.isMatch() );
hl7Query = HL7Query.compile("DECLARE result AS REQUIRED OBX SELECT MESSAGE WHERE result.7 = 'L' AND result.3.1 = 'GLU'");
result = hl7Query.evaluate(createMessage(new File("src/test/resources/hyperglycemia")));
assertFalse( result.isMatch() );
hl7Query = HL7Query.compile("DECLARE result AS REQUIRED OBX SELECT MESSAGE WHERE result.7 = 'H' AND result.3.1 = 'GLU'");
result = hl7Query.evaluate(createMessage(new File("src/test/resources/hypoglycemia")));
assertFalse( result.isMatch() );
hl7Query = HL7Query.compile("DECLARE result AS REQUIRED OBX SELECT MESSAGE WHERE result.7 = 'H' AND result.3.1 = 'GLU'");
result = hl7Query.evaluate(createMessage(new File("src/test/resources/hyperglycemia")));
assertTrue( result.isMatch() );
hl7Query = HL7Query.compile("DECLARE result AS REQUIRED OBX SELECT MESSAGE WHERE (result.7 = 'H') AND (result.3.1 = 'GLU')");
result = hl7Query.evaluate(createMessage(new File("src/test/resources/hyperglycemia")));
assertTrue( result.isMatch() );
hl7Query = HL7Query.compile("DECLARE result AS REQUIRED OBX SELECT MESSAGE WHERE ((result.7 = 'H') AND (result.3.1 = 'GLU'))");
result = hl7Query.evaluate(createMessage(new File("src/test/resources/hyperglycemia")));
assertTrue( result.isMatch() );
hl7Query = HL7Query.compile("DECLARE result AS REQUIRED OBX SELECT MESSAGE WHERE (( ((result.7 = 'H')) AND ( ((result.3.1 = 'GLU')) )))");
result = hl7Query.evaluate(createMessage(new File("src/test/resources/hyperglycemia")));
assertTrue( result.isMatch() );
}
@Test
public void testIsNull() throws HL7Exception, IOException {
HL7Query hl7Query = HL7Query.compile("DECLARE result AS REQUIRED OBX SELECT MESSAGE WHERE result.999 IS NULL");
QueryResult result = hl7Query.evaluate(createMessage(new File("src/test/resources/hypoglycemia")));
assertTrue( result.isMatch() );
hl7Query = HL7Query.compile("DECLARE result AS REQUIRED OBX SELECT MESSAGE WHERE result.1 IS NULL");
result = hl7Query.evaluate(createMessage(new File("src/test/resources/hypoglycemia")));
assertFalse( result.isMatch() );
hl7Query = HL7Query.compile("SELECT MESSAGE WHERE ZZZ IS NULL");
result = hl7Query.evaluate(createMessage(new File("src/test/resources/hypoglycemia")));
assertTrue( result.isMatch() );
hl7Query = HL7Query.compile("SELECT MESSAGE WHERE OBX IS NULL");
result = hl7Query.evaluate(createMessage(new File("src/test/resources/hypoglycemia")));
assertFalse( result.isMatch() );
hl7Query = HL7Query.compile("SELECT MESSAGE WHERE NK1.1 = '1' AND NK1.8 IS NULL");
result = hl7Query.evaluate(createMessage(new File("src/test/resources/unsolicited-vaccine-update-long")));
assertTrue( result.isMatch() );
}
@Test
public void testNotNull() throws HL7Exception, IOException {
HL7Query hl7Query = HL7Query.compile("DECLARE result AS REQUIRED OBX SELECT MESSAGE WHERE result.999 NOT NULL");
QueryResult result = hl7Query.evaluate(createMessage(new File("src/test/resources/hypoglycemia")));
assertFalse( result.isMatch() );
hl7Query = HL7Query.compile("DECLARE result AS REQUIRED OBX SELECT MESSAGE WHERE result.1 NOT NULL");
result = hl7Query.evaluate(createMessage(new File("src/test/resources/hypoglycemia")));
assertTrue( result.isMatch() );
hl7Query = HL7Query.compile("SELECT MESSAGE WHERE ZZZ NOT NULL");
result = hl7Query.evaluate(createMessage(new File("src/test/resources/hypoglycemia")));
assertFalse( result.isMatch() );
hl7Query = HL7Query.compile("SELECT MESSAGE WHERE OBX NOT NULL");
result = hl7Query.evaluate(createMessage(new File("src/test/resources/hypoglycemia")));
assertTrue( result.isMatch() );
hl7Query = HL7Query.compile("SELECT MESSAGE WHERE NK1.1 = '1' AND NK1.33 NOT NULL");
result = hl7Query.evaluate(createMessage(new File("src/test/resources/unsolicited-vaccine-update-long")));
assertTrue( result.isMatch() );
hl7Query = HL7Query.compile("SELECT MESSAGE WHERE NK1.1 = 1 AND NK1.33 NOT NULL");
result = hl7Query.evaluate(createMessage(new File("src/test/resources/unsolicited-vaccine-update-long")));
assertTrue( result.isMatch() );
}
private HL7Message createMessage(final File file) throws HL7Exception, IOException {
final byte[] bytes = Files.readAllBytes(file.toPath());
final String msgText = new String(bytes, "UTF-8");
final HapiContext hapiContext = new DefaultHapiContext();
hapiContext.setValidationContext(ValidationContextFactory.noValidation());
final PipeParser parser = hapiContext.getPipeParser();
final Message message = parser.parse(msgText);
return new HapiMessage(message);
}
@Test
@SuppressWarnings("unused")
public void createMessage() throws IOException, HL7Exception {
final byte[] bytes = Files.readAllBytes(Paths.get("src/test/resources/vaers-message-long"));
final String msgText = new String(bytes, "UTF-8");
final HapiContext hapiContext = new DefaultHapiContext();
hapiContext.setValidationContext(ValidationContextFactory.noValidation());
final PipeParser parser = hapiContext.getPipeParser();
final Message message = parser.parse(msgText);
final HL7Message hl7Msg = new HapiMessage(message);
}
}

View File

@ -0,0 +1,5 @@
MSH|^~\&|CERNER||PriorityHealth||||ORU^R01|Q479004375T431430612|P|2.3|
PID|||001677980||SMITH^CURTIS||19680219|M||||||||||929645156318|123456789|
PD1||||1234567890^LAST^FIRST^M^^^^^NPI|
OBR|1|341856649^HNAM_ORDERID|000002006326002362|648088^Basic Metabolic Panel|||20061122151600|||||||||1620^Hooker^Robert^L||||||20061122154733|||F|||||||||||20061122140000|
OBX|1|NM|GLU^Glucose Lvl|159|mg/dL|65-99^65^99|H|||F|||20061122154733|

View File

@ -0,0 +1,5 @@
MSH|^~\&|CERNER||PriorityHealth||||ORU^R01|Q479004375T431430612|P|2.3|
PID|||001677980||SMITH^CURTIS||19680219|M||||||||||929645156318|123456789|
PD1||||1234567890^LAST^FIRST^M^^^^^NPI|
OBR|1|341856649^HNAM_ORDERID|000002006326002362|648088^Basic Metabolic Panel|||20061122151600|||||||||1620^Hooker^Robert^L||||||20061122154733|||F|||||||||||20061122140000|
OBX|1|NM|GLU^Glucose Lvl|59|mg/dL|65-99^65^99|L|||F|||20061122154733|

View File

@ -0,0 +1,23 @@
MSH|^~\&|Lab1^1234^CLIA|^1234^CLIA|ELR^2.16.840.1.113883.19.3.2^ISO|SPH^2.16.840.1.113883.19.3.2^ISO|20110410140502-0500||ORU^R01^ORU_R01|1234567890|P^T|2.5.1|||NE|NE|USA||||USELR1.0^^2.16.840.1.114222.4.10.3^ISO
SFT|1|Level Seven Healthcare Software, Inc.^L^^^^&2.16.840.1.113883.19.4.6^ISO^XX^^^1234|1.2|An Lab System|56734||20080817
PID|1||36363636^^^MPI&2.16.840.1.113883.19.3.2.1&ISO^MR^A&2.16.840.1.113883.19.3.2.1&ISO~444333333^^^&2.16.840.1.113883.4.1^IS O^SS||Everyman^Adam^A^^^^L^^^^^^^BS|Mum^Martha^M^^^^M|19800602|M||2106-3^White^CDCREC^^^^04/24/2007|2222 Home Street^^Ann Arbor^MI^99999^USA^H||^PRN^PH^^1^555^5552004|^WPN^PH^^1^955^5551009|eng^English^ISO6392^^^^3/29/2007|M^Married^HL70002^^^^2.5.1||||||N^Not Hispanic or Latino^HL70189^^^^2.5.1||||||||N|||200808151000-0700| Reliable^2.16.840.1.113883.19.3.1^ISO
ORC|RE|23456^EHR^2.16.840.1.113883.19.3.2.3^ISO|9700123^Lab^2.16.840.1.113883.19.3.1.6^ISO|||||||||1234^Admit^Alan^A^III^Dr^^^&2.16.840.1.113883.19.4.6^ISO^L^^^EI^&2.16.840.1.113883.19.4.6^ISO^^^^^^^^MD||^WPN^PH^^1^555^5551005|||||||Level Seven Healthcare, Inc.^L^^^^&2.16.840.1.113883.19.4.6^ISO^XX^^^1234|1005 Healthcare Drive^^Ann Arbor^MI^99999^USA^B|^WPN^PH^^1^555^5553001|4444 Healthcare Drive^Suite 123^Ann Arbor^MI^99999^USA^B
OBR|1|23456^EHR^2.16.840.1.113883.19.3.2.3^ISO|9700123^Lab^2.16.840.1.113883.19.3.1.6^ISO|24323-8^Comprehensive metabolic 2000 panel in Serum or Plasma^LN^3436442^Metaboloic Panel 2000, Comprehensive^99USI|||201104101130-0500||||||angina|||1234^Admit^Alan^A^III^Dr^^^&2.16.840.1.113883.19.4.6^ISO^L^^^EI^&2.16.840.1.113883.19.4.6^ISO^^^^^^^^MD|^WPN^PH^^1^555^5551005|||||201104101405-0500|||F||||||413^Angina pectoris^I9CDX^^^^07/09/2008|1235&Slide&Stan&S&&Dr&MD&&DOC&2.16.840.1.113883.19.4.6&ISO
OBX|1|NM|17861-6^Calcium [Mass/volume] in Serum or Plasma^LN||27.3|mg/dL^milligrams per deciliter^UCUM|8.7-10.7|HH|||F|||201104101130-0500|||||201104101325-0500||||GHH Lab^L^^^^CLIA&2.16.840.1.113883.19.4.6&ISO^XX^^^1236|3434 Industrial Loop^^Ann Arbor^MI^99999^USA^B|9876543^Slide^Stan^S^^^^^NPPES&2.16.840.1.113883.19.4.6&ISO^L^^^NPI
OBX|2|NM|3094-0^Urea nitrogen [Mass/volume] in Serum of Plasma^LN||15|mg/dL^milligrams per deciliter^UCUM|6 to 23|N|||F|||201104101130-0500|||||201104101325-0500||||GHH Lab^L^^^^CLIA&2.16.840.1.113883.19.4.6&ISO^XX^^^1236|3434 Industrial Loop^^Ann Arbor^MI^99999^USA^B|9876543^Slide^Stan^S^^^^^NPPES&2.16.840.1.113883.19.4.6&ISO^L^^^NPI
OBX|3|NM|2160-0^Creatinine [Mass/volume] in Serum or Plasma^LN||1.8|mg/dL^milligrams per deciliter^UCUM|0.7 to 1.2|H|||F|||201104101130-0500|||||201104101325-0500||||GHH Lab^L^^^^CLIA&2.16.840.1.113883.19.4.6&ISO^XX^^^1236|3434 Industrial Loop^^Ann Arbor^MI^99999^USA^B|9876543^Slide^Stan^S^^^^^NPPES&2.16.840.1.113883.19.4.6&ISO^L^^^NPI
OBX|4|NM|3097-3^Urea nitrogen/Creatinine [Mass ratio] in Serum or Plasma^LN||15||6 to 25|N|||F|||201104101130-0500|||||201104101325-0500||||GHH Lab^L^^^^CLIA&2.16.840.1.113883.19.4.6&ISO^XX^^^1236|3434 Industrial Loop^^Ann Arbor^MI^99999^USA^B|9876543^Slide^Stan^S^^^^^NPPES&2.16.840.1.113883.19.4.6&ISO^L^^^NPI
OBX|5|NM|2885-2^Protein [Mass/volume] in Serum or Plasma^LN||8.9|gm/dL^grams per deciliter^UCUM|6.3 to 8.2|H|||F|||201104101130-0500|||||201104101325-0500||||GHH Lab^L^^^^CLIA&2.16.840.1.113883.19.4.6&ISO^XX^^^1236|3434 Industrial Loop^^Ann Arbor^MI^99999^USA^B|9876543^Slide^Stan^S^^^^^NPPES&2.16.840.1.113883.19.4.6&ISO^L^^^NPI
OBX|6|NM|1751-7^Albumin [Mass/volume] in Serum or Plasma^LN||5.7|gm/dL^grams per deciliter^UCUM|3.5 to 5.0|H|||F|||201104101130-0500|||||201104101325-0500||||GHH Lab^L^^^^CLIA&2.16.840.1.113883.19.4.6&ISO^XX^^^1236|3434 Industrial Loop^^Ann Arbor^MI^99999^USA^B|9876543^Slide^Stan^S^^^^^NPPES&2.16.840.1.113883.19.4.6&ISO^L^^^NPI
OBX|7|NM|2336-6^Globulin [Mass/volume] in Serum or Plasma^LN||4.7|gm/dL^grams per deciliter^UCUM|2.2 to 4.2|H|||F|||201104101130-0500|||||201104101325-0500||||GHH Lab^L^^^^CLIA&2.16.840.1.113883.19.4.6&ISO^XX^^^1236|3434 Industrial Loop^^Ann Arbor^MI^99999^USA^B|9876543^Slide^Stan^S^^^^^NPPES&2.16.840.1.113883.19.4.6&ISO^L^^^NPI
OBX|8|NM|1759-0^Albumin/Globulin [Mass ratio] in Serum or Plasma^LN||1.7||0.8 to 2.0|N|||F|||201104101130-0500|||||201104101325-0500||||GHH Lab^L^^^^CLIA&2.16.840.1.113883.19.4.6&ISO^XX^^^1236|3434 Industrial Loop^^Ann Arbor^MI^99999^USA^B|9876543^Slide^Stan^S^^^^^NPPES&2.16.840.1.113883.19.4.6&ISO^L^^^NPI
OBX|9|NM|1975-2^Bilirubin.total [Mass/volume] in Serum or Plasma^LN||0.7|mg/dL^milligrams per deciliter^UCUM|0.3 to 1.9|N|||F|||201104101130-0500|||||201104101325-0500||||GHH Lab^L^^^^CLIA&2.16.840.1.113883.19.4.6&ISO^XX^^^1236|3434 Industrial Loop^^Ann Arbor^MI^99999^USA^B|9876543^Slide^Stan^S^^^^^NPPES&2.16.840.1.113883.19.4.6&ISO^L^^^NPI
OBX|10|NM|2345-7^Glucose [Mass/volume] in Serum or Plasma^LN||55|mg/dL^milligrams per deciliter^UCUM|60 to 109|L|||F|||201104101130-0500|||||201104101325-0500||||GHH Lab^L^^^^CLIA&2.16.840.1.113883.19.4.6&ISO^XX^^^1236|3434 Industrial Loop^^Ann Arbor^MI^99999^USA^B|9876543^Slide^Stan^S^^^^^NPPES&2.16.840.1.113883.19.4.6&ISO^L^^^NPI
OBX|11|NM|6768-6^Alkaline phosphatase [Enzymatic activity/volume] in Serum or Plasma^LN||64|U/L^units per liter^UCUM|32 to 110|N|||F|||201104101130-0500|||||201104101325-0500||||GHH Lab^L^^^^CLIA&2.16.840.1.113883.19.4.6&ISO^XX^^^1236|3434 Industrial Loop^^Ann Arbor^MI^99999^USA^B|9876543^Slide^Stan^S^^^^^NPPES&2.16.840.1.113883.19.4.6&ISO^L^^^NPI
OBX|12|NM|1920-8^Aspartate aminotransferase [Enzymatic activity/volume] in Serum or Plasma^LN||6|U/L^units per liter^UCUM|6 to 18|N|||F|||201104101130-0500|||||201104101325-0500||||GHH Lab^L^^^^CLIA&2.16.840.1.113883.19.4.6&ISO^XX^^^1236|3434 Industrial Loop^^Ann Arbor^MI^99999^USA^B|9876543^Slide^Stan^S^^^^^NPPES&2.16.840.1.113883.19.4.6&ISO^L^^^NPI
OBX|13|NM|1742-6^Alanine aminotransferase [Enzymatic activity/volume] in Serum or Plasma^LN||10|U/L^units per liter^UCUM|5 to 35|N|||F|||201104101130-0500|||||201104101325-0500||||GHH Lab^L^^^^CLIA&2.16.840.1.113883.19.4.6&ISO^XX^^^1236|3434 Industrial Loop^^Ann Arbor^MI^99999^USA^B|9876543^Slide^Stan^S^^^^^NPPES&2.16.840.1.113883.19.4.6&ISO^L^^^NPI
OBX|14|NM|2951-2^Sodium [Moles/volume] in Serum or Plasma^LN||140|mmol/L^millimoles per liter^UCUM|137 to 147|N|||F|||201104101130-0500|||||201104101325-0500||||GHH Lab^L^^^^CLIA&2.16.840.1.113883.19.4.6&ISO^XX^^^1236|3434 Industrial Loop^^Ann Arbor^MI^99999^USA^B|9876543^Slide^Stan^S^^^^^NPPES&2.16.840.1.113883.19.4.6&ISO^L^^^NPI
OBX|15|NM|2823-3^Potassium [Moles/volume] in Serum or Plasma^LN||4.5|mmol/L^millimoles per liter^UCUM|3.4 to 5.3|N|||F|||201104101130-0500|||||201104101325-0500||||GHH Lab^L^^^^CLIA&2.16.840.1.113883.19.4.6&ISO^XX^^^1236|3434 Industrial Loop^^Ann Arbor^MI^99999^USA^B|9876543^Slide^Stan^S^^^^^NPPES&2.16.840.1.113883.19.4.6&ISO^L^^^NPI
OBX|16|NM|2075-0^Chloride [Moles/volume] in Serum or Plasma^LN||99|mmol/L^millimoles per liter^UCUM|99 to 108|N|||F|||201104101130-0500|||||201104101325-0500||||GHH Lab^L^^^^CLIA&2.16.840.1.113883.19.4.6&ISO^XX^^^1236|3434 Industrial Loop^^Ann Arbor^MI^99999^USA^B|9876543^Slide^Stan^S^^^^^NPPES&2.16.840.1.113883.19.4.6&ISO^L^^^NPI
OBX|17|NM|2028-9^Carbon dioxide, total [Moles/volume] in Serum or Plasma^LN||27|mmol/L^millimoles per liter^UCUM|22 to 29|N|||F|||201104101130-0500|||||201104101325-0500||||GHH Lab^L^^^^CLIA&2.16.840.1.113883.19.4.6&ISO^XX^^^1236|3434 Industrial Loop^^Ann Arbor^MI^99999^USA^B|9876543^Slide^Stan^S^^^^^NPPES&2.16.840.1.113883.19.4.6&ISO^L^^^NPI
SPM|1|23456&EHR&2.16.840.1.113883.19.3.2.3&ISO^9700122&Lab&2.16.840.1.113883.19.3.1.6&ISO||119364003^Serum specimen^SCT^^^^20080131|||||||||||||201104101130-0500|201104101130-0500

Some files were not shown because too many files have changed in this diff Show More