@Test public void testCreateMetricEntityDefinition(){ EntityDefinition entityDefinition = EntityDefinitionManager.createEntityDefinition(GenericMetricEntity.class); Assert.assertNotNull(entityDefinition); }
@SuppressWarnings("unchecked") public static EntityDefinition createEntityDefinition(Class<? extends TaggedLogAPIEntity> cls) { final EntityDefinition ed = new EntityDefinition(); ed.setEntityClass(cls); Table table = cls.getAnnotation(Table.class); if(table == null || table.value().isEmpty()){ throw new IllegalArgumentException("Entity class must have a non-empty table name annotated with @Table"); } String tableName = table.value(); if(EagleConfigFactory.load().isTableNamePrefixedWithEnvironment()){ tableName = EagleConfigFactory.load().getEnv() + "_" + tableName; } ed.setTable(tableName); ColumnFamily family = cls.getAnnotation(ColumnFamily.class); if(family == null || family.value().isEmpty()){ throw new IllegalArgumentException("Entity class must have a non-empty column family name annotated with @ColumnFamily"); } ed.setColumnFamily(family.value()); Prefix prefix = cls.getAnnotation(Prefix.class); if(prefix == null || prefix.value().isEmpty()){ throw new IllegalArgumentException("Entity class must have a non-empty prefix name annotated with @Prefix"); } ed.setPrefix(prefix.value()); TimeSeries ts = cls.getAnnotation(TimeSeries.class); if(ts == null){ throw new IllegalArgumentException("Entity class must have a non-empty timeseries name annotated with @TimeSeries"); } ed.setTimeSeries(ts.value()); Service service = cls.getAnnotation(Service.class); if(service == null || service.value().isEmpty()){ ed.setService(cls.getSimpleName()); } else { ed.setService(service.value()); } Metric m = cls.getAnnotation(Metric.class); Map<String, Class<?>> dynamicFieldTypes = new HashMap<String, Class<?>>(); if(m != null){ if(!ts.value()){ throw new IllegalArgumentException("Metric entity must be time series as well"); } MetricDefinition md = new MetricDefinition(); md.setInterval(m.interval()); ed.setMetricDefinition(md); } java.lang.reflect.Field[] fields = cls.getDeclaredFields(); for(java.lang.reflect.Field f : fields){ Column column = f.getAnnotation(Column.class); if(column == null || column.value().isEmpty()){ continue; } Class<?> fldCls = f.getType(); checkFieldTypeForMetric(ed.getMetricDefinition(), f.getName(), fldCls, dynamicFieldTypes); Qualifier q = new Qualifier(); q.setDisplayName(f.getName()); q.setQualifierName(column.value()); EntitySerDeser<?> serDeser = _serDeserMap.get(fldCls); if(serDeser == null){ throw new IllegalArgumentException(fldCls.getName() + " in field " + f.getName() + " of entity " + cls.getSimpleName() + " has no serializer associated "); } else { q.setSerDeser((EntitySerDeser<Object>)serDeser); } ed.getQualifierNameMap().put(q.getQualifierName(), q); ed.getDisplayNameMap().put(q.getDisplayName(), q); final String propertyName = f.getName().substring(0,1).toUpperCase() + f.getName().substring(1); String getterName = "get" + propertyName; try { Method method = cls.getMethod(getterName); ed.getQualifierGetterMap().put(f.getName(), method); } catch (Exception e) { getterName = "is" + propertyName; try { Method method = cls.getMethod(getterName); ed.getQualifierGetterMap().put(f.getName(), method); } catch (Exception e1) { throw new IllegalArgumentException("Field " + f.getName() + " hasn't defined valid getter method: " + getterName, e); } } if(LOG.isDebugEnabled()) LOG.debug("Field registered " + q); } if(ed.getMetricDefinition() != null){ Class<?> metricCls = createDynamicClassForMetric(cls.getName()+"_SingleTimestamp", dynamicFieldTypes); ed.getMetricDefinition().setSingleTimestampEntityClass(metricCls); } final Partition partition = cls.getAnnotation(Partition.class); if (partition != null) { final String[] partitions = partition.value(); ed.setPartitions(partitions); for (String part : partitions) { if (!ed.isTag(part)) { throw new IllegalArgumentException("Partition field can't be column field, must be tag field. " + "Partition name: " + part); } } } final Indexes indexes = cls.getAnnotation(Indexes.class); if (indexes != null) { final Index[] inds = indexes.value(); final IndexDefinition[] indexDefinitions = new IndexDefinition[inds.length]; for (int i = 0; i < inds.length; ++i) { final Index ind = inds[i]; indexDefinitions[i] = new IndexDefinition(ed, ind); } ed.setIndexes(indexDefinitions); } final ServicePath path = cls.getAnnotation(ServicePath.class); if (path != null) { if (path.path() != null && (!path.path().isEmpty())) { ed.setServiceCreationPath(path.path()); } } return ed; }
EntityDefinitionManager { @SuppressWarnings("unchecked") public static EntityDefinition createEntityDefinition(Class<? extends TaggedLogAPIEntity> cls) { final EntityDefinition ed = new EntityDefinition(); ed.setEntityClass(cls); Table table = cls.getAnnotation(Table.class); if(table == null || table.value().isEmpty()){ throw new IllegalArgumentException("Entity class must have a non-empty table name annotated with @Table"); } String tableName = table.value(); if(EagleConfigFactory.load().isTableNamePrefixedWithEnvironment()){ tableName = EagleConfigFactory.load().getEnv() + "_" + tableName; } ed.setTable(tableName); ColumnFamily family = cls.getAnnotation(ColumnFamily.class); if(family == null || family.value().isEmpty()){ throw new IllegalArgumentException("Entity class must have a non-empty column family name annotated with @ColumnFamily"); } ed.setColumnFamily(family.value()); Prefix prefix = cls.getAnnotation(Prefix.class); if(prefix == null || prefix.value().isEmpty()){ throw new IllegalArgumentException("Entity class must have a non-empty prefix name annotated with @Prefix"); } ed.setPrefix(prefix.value()); TimeSeries ts = cls.getAnnotation(TimeSeries.class); if(ts == null){ throw new IllegalArgumentException("Entity class must have a non-empty timeseries name annotated with @TimeSeries"); } ed.setTimeSeries(ts.value()); Service service = cls.getAnnotation(Service.class); if(service == null || service.value().isEmpty()){ ed.setService(cls.getSimpleName()); } else { ed.setService(service.value()); } Metric m = cls.getAnnotation(Metric.class); Map<String, Class<?>> dynamicFieldTypes = new HashMap<String, Class<?>>(); if(m != null){ if(!ts.value()){ throw new IllegalArgumentException("Metric entity must be time series as well"); } MetricDefinition md = new MetricDefinition(); md.setInterval(m.interval()); ed.setMetricDefinition(md); } java.lang.reflect.Field[] fields = cls.getDeclaredFields(); for(java.lang.reflect.Field f : fields){ Column column = f.getAnnotation(Column.class); if(column == null || column.value().isEmpty()){ continue; } Class<?> fldCls = f.getType(); checkFieldTypeForMetric(ed.getMetricDefinition(), f.getName(), fldCls, dynamicFieldTypes); Qualifier q = new Qualifier(); q.setDisplayName(f.getName()); q.setQualifierName(column.value()); EntitySerDeser<?> serDeser = _serDeserMap.get(fldCls); if(serDeser == null){ throw new IllegalArgumentException(fldCls.getName() + " in field " + f.getName() + " of entity " + cls.getSimpleName() + " has no serializer associated "); } else { q.setSerDeser((EntitySerDeser<Object>)serDeser); } ed.getQualifierNameMap().put(q.getQualifierName(), q); ed.getDisplayNameMap().put(q.getDisplayName(), q); final String propertyName = f.getName().substring(0,1).toUpperCase() + f.getName().substring(1); String getterName = "get" + propertyName; try { Method method = cls.getMethod(getterName); ed.getQualifierGetterMap().put(f.getName(), method); } catch (Exception e) { getterName = "is" + propertyName; try { Method method = cls.getMethod(getterName); ed.getQualifierGetterMap().put(f.getName(), method); } catch (Exception e1) { throw new IllegalArgumentException("Field " + f.getName() + " hasn't defined valid getter method: " + getterName, e); } } if(LOG.isDebugEnabled()) LOG.debug("Field registered " + q); } if(ed.getMetricDefinition() != null){ Class<?> metricCls = createDynamicClassForMetric(cls.getName()+"_SingleTimestamp", dynamicFieldTypes); ed.getMetricDefinition().setSingleTimestampEntityClass(metricCls); } final Partition partition = cls.getAnnotation(Partition.class); if (partition != null) { final String[] partitions = partition.value(); ed.setPartitions(partitions); for (String part : partitions) { if (!ed.isTag(part)) { throw new IllegalArgumentException("Partition field can't be column field, must be tag field. " + "Partition name: " + part); } } } final Indexes indexes = cls.getAnnotation(Indexes.class); if (indexes != null) { final Index[] inds = indexes.value(); final IndexDefinition[] indexDefinitions = new IndexDefinition[inds.length]; for (int i = 0; i < inds.length; ++i) { final Index ind = inds[i]; indexDefinitions[i] = new IndexDefinition(ed, ind); } ed.setIndexes(indexDefinitions); } final ServicePath path = cls.getAnnotation(ServicePath.class); if (path != null) { if (path.path() != null && (!path.path().isEmpty())) { ed.setServiceCreationPath(path.path()); } } return ed; } }
EntityDefinitionManager { @SuppressWarnings("unchecked") public static EntityDefinition createEntityDefinition(Class<? extends TaggedLogAPIEntity> cls) { final EntityDefinition ed = new EntityDefinition(); ed.setEntityClass(cls); Table table = cls.getAnnotation(Table.class); if(table == null || table.value().isEmpty()){ throw new IllegalArgumentException("Entity class must have a non-empty table name annotated with @Table"); } String tableName = table.value(); if(EagleConfigFactory.load().isTableNamePrefixedWithEnvironment()){ tableName = EagleConfigFactory.load().getEnv() + "_" + tableName; } ed.setTable(tableName); ColumnFamily family = cls.getAnnotation(ColumnFamily.class); if(family == null || family.value().isEmpty()){ throw new IllegalArgumentException("Entity class must have a non-empty column family name annotated with @ColumnFamily"); } ed.setColumnFamily(family.value()); Prefix prefix = cls.getAnnotation(Prefix.class); if(prefix == null || prefix.value().isEmpty()){ throw new IllegalArgumentException("Entity class must have a non-empty prefix name annotated with @Prefix"); } ed.setPrefix(prefix.value()); TimeSeries ts = cls.getAnnotation(TimeSeries.class); if(ts == null){ throw new IllegalArgumentException("Entity class must have a non-empty timeseries name annotated with @TimeSeries"); } ed.setTimeSeries(ts.value()); Service service = cls.getAnnotation(Service.class); if(service == null || service.value().isEmpty()){ ed.setService(cls.getSimpleName()); } else { ed.setService(service.value()); } Metric m = cls.getAnnotation(Metric.class); Map<String, Class<?>> dynamicFieldTypes = new HashMap<String, Class<?>>(); if(m != null){ if(!ts.value()){ throw new IllegalArgumentException("Metric entity must be time series as well"); } MetricDefinition md = new MetricDefinition(); md.setInterval(m.interval()); ed.setMetricDefinition(md); } java.lang.reflect.Field[] fields = cls.getDeclaredFields(); for(java.lang.reflect.Field f : fields){ Column column = f.getAnnotation(Column.class); if(column == null || column.value().isEmpty()){ continue; } Class<?> fldCls = f.getType(); checkFieldTypeForMetric(ed.getMetricDefinition(), f.getName(), fldCls, dynamicFieldTypes); Qualifier q = new Qualifier(); q.setDisplayName(f.getName()); q.setQualifierName(column.value()); EntitySerDeser<?> serDeser = _serDeserMap.get(fldCls); if(serDeser == null){ throw new IllegalArgumentException(fldCls.getName() + " in field " + f.getName() + " of entity " + cls.getSimpleName() + " has no serializer associated "); } else { q.setSerDeser((EntitySerDeser<Object>)serDeser); } ed.getQualifierNameMap().put(q.getQualifierName(), q); ed.getDisplayNameMap().put(q.getDisplayName(), q); final String propertyName = f.getName().substring(0,1).toUpperCase() + f.getName().substring(1); String getterName = "get" + propertyName; try { Method method = cls.getMethod(getterName); ed.getQualifierGetterMap().put(f.getName(), method); } catch (Exception e) { getterName = "is" + propertyName; try { Method method = cls.getMethod(getterName); ed.getQualifierGetterMap().put(f.getName(), method); } catch (Exception e1) { throw new IllegalArgumentException("Field " + f.getName() + " hasn't defined valid getter method: " + getterName, e); } } if(LOG.isDebugEnabled()) LOG.debug("Field registered " + q); } if(ed.getMetricDefinition() != null){ Class<?> metricCls = createDynamicClassForMetric(cls.getName()+"_SingleTimestamp", dynamicFieldTypes); ed.getMetricDefinition().setSingleTimestampEntityClass(metricCls); } final Partition partition = cls.getAnnotation(Partition.class); if (partition != null) { final String[] partitions = partition.value(); ed.setPartitions(partitions); for (String part : partitions) { if (!ed.isTag(part)) { throw new IllegalArgumentException("Partition field can't be column field, must be tag field. " + "Partition name: " + part); } } } final Indexes indexes = cls.getAnnotation(Indexes.class); if (indexes != null) { final Index[] inds = indexes.value(); final IndexDefinition[] indexDefinitions = new IndexDefinition[inds.length]; for (int i = 0; i < inds.length; ++i) { final Index ind = inds[i]; indexDefinitions[i] = new IndexDefinition(ed, ind); } ed.setIndexes(indexDefinitions); } final ServicePath path = cls.getAnnotation(ServicePath.class); if (path != null) { if (path.path() != null && (!path.path().isEmpty())) { ed.setServiceCreationPath(path.path()); } } return ed; }  }
EntityDefinitionManager { @SuppressWarnings("unchecked") public static EntityDefinition createEntityDefinition(Class<? extends TaggedLogAPIEntity> cls) { final EntityDefinition ed = new EntityDefinition(); ed.setEntityClass(cls); Table table = cls.getAnnotation(Table.class); if(table == null || table.value().isEmpty()){ throw new IllegalArgumentException("Entity class must have a non-empty table name annotated with @Table"); } String tableName = table.value(); if(EagleConfigFactory.load().isTableNamePrefixedWithEnvironment()){ tableName = EagleConfigFactory.load().getEnv() + "_" + tableName; } ed.setTable(tableName); ColumnFamily family = cls.getAnnotation(ColumnFamily.class); if(family == null || family.value().isEmpty()){ throw new IllegalArgumentException("Entity class must have a non-empty column family name annotated with @ColumnFamily"); } ed.setColumnFamily(family.value()); Prefix prefix = cls.getAnnotation(Prefix.class); if(prefix == null || prefix.value().isEmpty()){ throw new IllegalArgumentException("Entity class must have a non-empty prefix name annotated with @Prefix"); } ed.setPrefix(prefix.value()); TimeSeries ts = cls.getAnnotation(TimeSeries.class); if(ts == null){ throw new IllegalArgumentException("Entity class must have a non-empty timeseries name annotated with @TimeSeries"); } ed.setTimeSeries(ts.value()); Service service = cls.getAnnotation(Service.class); if(service == null || service.value().isEmpty()){ ed.setService(cls.getSimpleName()); } else { ed.setService(service.value()); } Metric m = cls.getAnnotation(Metric.class); Map<String, Class<?>> dynamicFieldTypes = new HashMap<String, Class<?>>(); if(m != null){ if(!ts.value()){ throw new IllegalArgumentException("Metric entity must be time series as well"); } MetricDefinition md = new MetricDefinition(); md.setInterval(m.interval()); ed.setMetricDefinition(md); } java.lang.reflect.Field[] fields = cls.getDeclaredFields(); for(java.lang.reflect.Field f : fields){ Column column = f.getAnnotation(Column.class); if(column == null || column.value().isEmpty()){ continue; } Class<?> fldCls = f.getType(); checkFieldTypeForMetric(ed.getMetricDefinition(), f.getName(), fldCls, dynamicFieldTypes); Qualifier q = new Qualifier(); q.setDisplayName(f.getName()); q.setQualifierName(column.value()); EntitySerDeser<?> serDeser = _serDeserMap.get(fldCls); if(serDeser == null){ throw new IllegalArgumentException(fldCls.getName() + " in field " + f.getName() + " of entity " + cls.getSimpleName() + " has no serializer associated "); } else { q.setSerDeser((EntitySerDeser<Object>)serDeser); } ed.getQualifierNameMap().put(q.getQualifierName(), q); ed.getDisplayNameMap().put(q.getDisplayName(), q); final String propertyName = f.getName().substring(0,1).toUpperCase() + f.getName().substring(1); String getterName = "get" + propertyName; try { Method method = cls.getMethod(getterName); ed.getQualifierGetterMap().put(f.getName(), method); } catch (Exception e) { getterName = "is" + propertyName; try { Method method = cls.getMethod(getterName); ed.getQualifierGetterMap().put(f.getName(), method); } catch (Exception e1) { throw new IllegalArgumentException("Field " + f.getName() + " hasn't defined valid getter method: " + getterName, e); } } if(LOG.isDebugEnabled()) LOG.debug("Field registered " + q); } if(ed.getMetricDefinition() != null){ Class<?> metricCls = createDynamicClassForMetric(cls.getName()+"_SingleTimestamp", dynamicFieldTypes); ed.getMetricDefinition().setSingleTimestampEntityClass(metricCls); } final Partition partition = cls.getAnnotation(Partition.class); if (partition != null) { final String[] partitions = partition.value(); ed.setPartitions(partitions); for (String part : partitions) { if (!ed.isTag(part)) { throw new IllegalArgumentException("Partition field can't be column field, must be tag field. " + "Partition name: " + part); } } } final Indexes indexes = cls.getAnnotation(Indexes.class); if (indexes != null) { final Index[] inds = indexes.value(); final IndexDefinition[] indexDefinitions = new IndexDefinition[inds.length]; for (int i = 0; i < inds.length; ++i) { final Index ind = inds[i]; indexDefinitions[i] = new IndexDefinition(ed, ind); } ed.setIndexes(indexDefinitions); } final ServicePath path = cls.getAnnotation(ServicePath.class); if (path != null) { if (path.path() != null && (!path.path().isEmpty())) { ed.setServiceCreationPath(path.path()); } } return ed; }  @SuppressWarnings("rawtypes") static EntitySerDeser getSerDeser(Class<?> clazz); static int getIDBySerDerClass(Class<?> clazz); static Class<?> getClassByID(int id); static void registerEntity(Class<? extends TaggedLogAPIEntity> clazz); @Deprecated static void registerEntity(String serviceName, Class<? extends TaggedLogAPIEntity> clazz); static void registerEntity(EntityDefinition entityDef); static void registerEntity(String serviceName, EntityDefinition entityDef); static EntityDefinition getEntityByServiceName(String serviceName); static EntityDefinition getEntityDefinitionByEntityClass(Class<? extends TaggedLogAPIEntity> clazz); static void registerSerDeser(Class<?> clazz, EntitySerDeser<?> entitySerDeser); static boolean isTimeSeries(Class<? extends TaggedLogAPIEntity> clazz); @SuppressWarnings("unchecked") static EntityDefinition createEntityDefinition(Class<? extends TaggedLogAPIEntity> cls); static Map<String, EntityDefinition> entities(); }
EntityDefinitionManager { @SuppressWarnings("unchecked") public static EntityDefinition createEntityDefinition(Class<? extends TaggedLogAPIEntity> cls) { final EntityDefinition ed = new EntityDefinition(); ed.setEntityClass(cls); Table table = cls.getAnnotation(Table.class); if(table == null || table.value().isEmpty()){ throw new IllegalArgumentException("Entity class must have a non-empty table name annotated with @Table"); } String tableName = table.value(); if(EagleConfigFactory.load().isTableNamePrefixedWithEnvironment()){ tableName = EagleConfigFactory.load().getEnv() + "_" + tableName; } ed.setTable(tableName); ColumnFamily family = cls.getAnnotation(ColumnFamily.class); if(family == null || family.value().isEmpty()){ throw new IllegalArgumentException("Entity class must have a non-empty column family name annotated with @ColumnFamily"); } ed.setColumnFamily(family.value()); Prefix prefix = cls.getAnnotation(Prefix.class); if(prefix == null || prefix.value().isEmpty()){ throw new IllegalArgumentException("Entity class must have a non-empty prefix name annotated with @Prefix"); } ed.setPrefix(prefix.value()); TimeSeries ts = cls.getAnnotation(TimeSeries.class); if(ts == null){ throw new IllegalArgumentException("Entity class must have a non-empty timeseries name annotated with @TimeSeries"); } ed.setTimeSeries(ts.value()); Service service = cls.getAnnotation(Service.class); if(service == null || service.value().isEmpty()){ ed.setService(cls.getSimpleName()); } else { ed.setService(service.value()); } Metric m = cls.getAnnotation(Metric.class); Map<String, Class<?>> dynamicFieldTypes = new HashMap<String, Class<?>>(); if(m != null){ if(!ts.value()){ throw new IllegalArgumentException("Metric entity must be time series as well"); } MetricDefinition md = new MetricDefinition(); md.setInterval(m.interval()); ed.setMetricDefinition(md); } java.lang.reflect.Field[] fields = cls.getDeclaredFields(); for(java.lang.reflect.Field f : fields){ Column column = f.getAnnotation(Column.class); if(column == null || column.value().isEmpty()){ continue; } Class<?> fldCls = f.getType(); checkFieldTypeForMetric(ed.getMetricDefinition(), f.getName(), fldCls, dynamicFieldTypes); Qualifier q = new Qualifier(); q.setDisplayName(f.getName()); q.setQualifierName(column.value()); EntitySerDeser<?> serDeser = _serDeserMap.get(fldCls); if(serDeser == null){ throw new IllegalArgumentException(fldCls.getName() + " in field " + f.getName() + " of entity " + cls.getSimpleName() + " has no serializer associated "); } else { q.setSerDeser((EntitySerDeser<Object>)serDeser); } ed.getQualifierNameMap().put(q.getQualifierName(), q); ed.getDisplayNameMap().put(q.getDisplayName(), q); final String propertyName = f.getName().substring(0,1).toUpperCase() + f.getName().substring(1); String getterName = "get" + propertyName; try { Method method = cls.getMethod(getterName); ed.getQualifierGetterMap().put(f.getName(), method); } catch (Exception e) { getterName = "is" + propertyName; try { Method method = cls.getMethod(getterName); ed.getQualifierGetterMap().put(f.getName(), method); } catch (Exception e1) { throw new IllegalArgumentException("Field " + f.getName() + " hasn't defined valid getter method: " + getterName, e); } } if(LOG.isDebugEnabled()) LOG.debug("Field registered " + q); } if(ed.getMetricDefinition() != null){ Class<?> metricCls = createDynamicClassForMetric(cls.getName()+"_SingleTimestamp", dynamicFieldTypes); ed.getMetricDefinition().setSingleTimestampEntityClass(metricCls); } final Partition partition = cls.getAnnotation(Partition.class); if (partition != null) { final String[] partitions = partition.value(); ed.setPartitions(partitions); for (String part : partitions) { if (!ed.isTag(part)) { throw new IllegalArgumentException("Partition field can't be column field, must be tag field. " + "Partition name: " + part); } } } final Indexes indexes = cls.getAnnotation(Indexes.class); if (indexes != null) { final Index[] inds = indexes.value(); final IndexDefinition[] indexDefinitions = new IndexDefinition[inds.length]; for (int i = 0; i < inds.length; ++i) { final Index ind = inds[i]; indexDefinitions[i] = new IndexDefinition(ed, ind); } ed.setIndexes(indexDefinitions); } final ServicePath path = cls.getAnnotation(ServicePath.class); if (path != null) { if (path.path() != null && (!path.path().isEmpty())) { ed.setServiceCreationPath(path.path()); } } return ed; }  @SuppressWarnings("rawtypes") static EntitySerDeser getSerDeser(Class<?> clazz); static int getIDBySerDerClass(Class<?> clazz); static Class<?> getClassByID(int id); static void registerEntity(Class<? extends TaggedLogAPIEntity> clazz); @Deprecated static void registerEntity(String serviceName, Class<? extends TaggedLogAPIEntity> clazz); static void registerEntity(EntityDefinition entityDef); static void registerEntity(String serviceName, EntityDefinition entityDef); static EntityDefinition getEntityByServiceName(String serviceName); static EntityDefinition getEntityDefinitionByEntityClass(Class<? extends TaggedLogAPIEntity> clazz); static void registerSerDeser(Class<?> clazz, EntitySerDeser<?> entitySerDeser); static boolean isTimeSeries(Class<? extends TaggedLogAPIEntity> clazz); @SuppressWarnings("unchecked") static EntityDefinition createEntityDefinition(Class<? extends TaggedLogAPIEntity> cls); static Map<String, EntityDefinition> entities();  }